gpt4 book ai didi

haskell - 递归 IO 函数中的内存泄漏 - PAP

转载 作者:行者123 更新时间:2023-12-03 07:30:58 25 4
gpt4 key购买 nike

我编写了一个名为 amqp-worker 的库它提供了一个名为 worker 的函数,该函数轮询消息队列(如 RabbitMQ )以查找消息,并在找到消息时调用处理程序。然后返回轮询。

内存泄漏。我已经对其进行了分析,图表显示 PAP(偏函数应用程序)是罪魁祸首。 我的代码哪里有泄漏?在 IO 中使用 forever 进行循环时,如何避免泄漏?

enter image description here

以下是一些相关函数。 The full source is here .

Example Program 。这泄露了

main :: IO ()
main = do
-- connect
conn <- Worker.connect (fromURI "amqp://guest:guest@localhost:5672")

-- initialize the queues
Worker.initQueue conn queue
Worker.initQueue conn results

-- publish a message
Worker.publish conn queue (TestMessage "hello world")

-- create a worker, the program loops here
Worker.worker def conn queue onError (onMessage conn)

worker

worker :: (FromJSON a, MonadBaseControl IO m, MonadCatch m) => WorkerOptions -> Connection -> Queue key a -> (WorkerException SomeException -> m ()) -> (Message a -> m ()) -> m ()
worker opts conn queue onError action =
forever $ do
eres <- consumeNext (pollDelay opts) conn queue
case eres of
Error (ParseError reason bd) ->
onError (MessageParseError bd reason)

Parsed msg ->
catch
(action msg)
(onError . OtherException (body msg))
liftBase $ threadDelay (loopDelay opts)

consumeNext

consumeNext :: (FromJSON msg, MonadBaseControl IO m) => Microseconds -> Connection -> Queue key msg -> m (ConsumeResult msg)
consumeNext pd conn queue =
poll pd $ consume conn queue

poll

poll :: (MonadBaseControl IO m) => Int -> m (Maybe a) -> m a
poll us action = do
ma <- action
case ma of
Just a -> return a
Nothing -> do
liftBase $ threadDelay us
poll us action

最佳答案

这是一个非常简单的示例,可以演示您的问题:

main :: IO ()
main = worker

{-# NOINLINE worker #-}
worker :: (Monad m) => m ()
worker =
let loop = poll >> loop
in loop

poll :: (Monad m) => m a
poll = return () >> poll

如果删除 NOINLINE,或将 m 专门化为IO(使用-O编译时),泄漏消失了。

我写了详细的blogpost关于为什么正是这段代码泄漏了内存。正如里德在他的书中指出的那样,快速总结是答案是,代码创建并记住一系列部分应用程序>>s.

我还提交了 ghc ticket关于这个。

关于haskell - 递归 IO 函数中的内存泄漏 - PAP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41306593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com