我試圖修改Data.Binary.PutM monad成monad變換器。於是我開始了變化它的定義從爲什麼將Data.Binary.Put monad更改爲變換器會產生內存泄漏?
newtype PutM a = Put { unPut :: PairS a }
到
newtype PutM a = Put { unPut :: Identity (PairS a) }
那麼當然我改變了回報和>> =函數的實現:
來源:
return a = Put $ PairS a mempty
{-# INLINE return #-}
m >>= k = Put $
let PairS a w = unPut m
PairS b w1 = unPut (k a)
in PairS b (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $
let PairS _ w = unPut m
PairS b w1 = unPut k
in PairS b (w `mappend` w1)
{-# INLINE (>>) #-}
收件人:
return a = Put $! return $! PairS a mempty
{-# INLINE return #-}
m >>= k = Put $!
do PairS a w <- unPut m
PairS b w1 <- unPut (k a)
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $!
do PairS _ w <- unPut m
PairS b w1 <- unPut k
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>) #-}
好像PutM monad只是一個Writer monad。不幸的是(again)造成了空間泄漏。我很清楚(或是否?)ghc推遲評估某處,但我嘗試將$!
而不是$
無處不在,正如某些教程所建議的,但這並沒有幫助。另外,我不確定內存分析器是如何幫助的,如果它告訴我的是這樣的:
。
以及物品是否完整,這是存儲配置文件使用原始Data.Binary.Put單子時,我得到:
如果有興趣,here是我使用來測試它的代碼和我使用的編譯,運行和創建存儲輪廓線是:
ghc -auto-all -fforce-recomp -O2 --make test5.hs && ./test5 +RTS -hT && hp2ps -c test5.hp && okular test5.ps
我希望我不是被我的內存泄漏問題傳奇討厭任何人。我發現互聯網上沒有很多關於這個話題的良好資源,這讓我們無言以對。
感謝您的期待。
彼得嗨 - 我不相信你有內Data.Binary即「太空泄漏」一些錯誤的數據處理停止垃圾收集。我想爲什麼你要構建一個巨大的內存配置文件是因爲你的數據結構(一棵樹)沒有流 - 在完成序列化之前它必須在內存中(加上一個類似的大輸出ByteString)。我的直覺是問題是樹 - 而不是Data.Binary。 – 2011-03-09 12:58:00
嗨@stephen,我忘了提及,如果我使用原始的Data.Binary.Put monad(沒有Identity的那個),那麼它流很好(沒有通知的內存增加)。我的理解是,如果記憶純粹是由樹結構消耗的,記憶力的增加會在兩種情況下表現出來。 – 2011-03-09 13:23:34
你能給我們發一些更多的代碼嗎? – fuz 2011-03-09 13:27:30