Data.Binary.Put 모나드를 다른 바이트로 랩핑하려고합니다. 나중에 "쓸 바이트 수"또는 "파일의 현재 위치"와 같은 질문을 나중에 물어볼 수 있습니다. 그러나 심지어 아주 사소한 랩 좋아 :왜 Data.Binary.Put 모나드를 래핑하면 메모리 누수가 발생합니까?
data Writer1M a = Writer1M { write :: P.PutM a }
or
data Writer2M a = Writer2M { write :: (a, P.Put) }
거대한 공간의 누출을 만들고 프로그램은 일반적으로 (RAM 4GB의를 복용 후) 충돌합니다. 여기에 지금까지 시도한 것입니다 :
-- This works well and consumes almost no memory.
type Writer = P.Put
writer :: P.Put -> Writer
writer put = put
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut writer)
-- This one will cause memory leak.
data Writer1M a = Writer1M { write :: P.PutM a }
instance Monad Writer1M where
return a = Writer1M $ return a
ma >>= f = Writer1M $ (write ma) >>= \a -> write $ f a
type WriterM = Writer1M
type Writer = WriterM()
writer :: P.Put -> Writer
writer put = Writer1M $ put
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut $ write writer)
-- This one will crash as well with exactly the
-- same memory foot print as Writer1M
data Writer2M a = Writer2M { write :: (a, P.Put) }
instance Monad Writer2M where
return a = Writer2M $ (a, return())
ma >>= f = Writer2M $ (b, p >> p')
where (a,p) = write ma
(b,p') = write $ f a
type WriterM = Writer2M
type Writer = WriterM()
writer :: P.Put -> Writer
writer put = Writer2M $ ((), put)
writeToFile :: String -> Writer -> IO()
writeToFile path writer = BL.writeFile path (P.runPut $ snd $ write writer)
내가 하스켈에 새로 온 사람이 나에게 어떤 sence을하지 않으며, 그러나 래퍼 모나드 그래서 내가 거기 같은데요 아주 사소한 것 나는 분명히 뭔가 빠져있다.
감사합니다.
UPDATE
: http://hpaste.org/43400/why_wrapping_the_databinarypUPDATE2 : 여기 문제를 보여주는 샘플 코드 또한이 질문에 here에 두 번째 부분이있다.
어떤 컴파일러 플래그를 사용하고 있습니까? –
질문을 한 후에 -O2로 시도했지만 (이전에는 아무 것도 사용하지 않았지만) 메모리 발자국이 변경되지 않았습니다. –
다른 사람들이 자신의 테스트 프로그램을 만들 필요가 없도록 간단한 테스트 프로그램을 게시 할 수 있습니까? –