
I wrote a very simple Fudgets program (just copies stdin to stdout, no graphics involved) -------- leaktest.hs ------------------ module Main where import Graphics.UI.Fudgets.Fudgets main = fudlogue (stdoutF >==< stdinF) and ran it like this: yes | leaktest I found out that the program grows in memory. Its "traditional" analog: -------- leaktest2.hs ----------------- module Main where import System.IO main = do hGetLine stdin >>= hPutStrLn stdout main works in constant space. I tried to observe the GC realtime stats with +RTS -Sstderr -M600K It turns out, garbage is collected, number of allocated and collected bytes are mostly constant, and number of live bytes fluctuates, but averagely stays the same: Alloc Collect Live GC GC TOT TOT Page Flts bytes bytes bytes user elap user elap 316720 262144 9528 0.00 0.00 0.02 0.02 144 499 (Gen: 0) 262128 262144 22188 0.01 0.01 0.03 0.04 0 3 (Gen: 0) 262128 262144 8276 0.00 0.00 0.04 0.05 0 0 (Gen: 0) 262128 262144 24612 0.01 0.01 0.05 0.06 0 0 (Gen: 0) 262128 262144 10680 0.00 0.00 0.06 0.07 0 0 (Gen: 0) 262128 262144 23376 0.00 0.00 0.06 0.08 0 0 (Gen: 0) 262128 262144 9444 0.00 0.00 0.07 0.09 0 0 (Gen: 0) 262012 262144 25492 0.00 0.00 0.07 0.10 0 0 (Gen: 0) ... program grows to 10M ......... 262128 262144 1684 0.01 0.01 42.33 66.10 0 0 (Gen: 0) 262128 262144 13396 0.01 0.01 42.34 66.11 0 0 (Gen: 0) 262124 262144 25540 0.01 0.01 42.35 66.12 0 0 (Gen: 0) 262128 262144 11988 0.00 0.00 42.35 66.13 0 0 (Gen: 0) 262128 262144 1760 0.00 0.00 42.36 66.14 0 0 (Gen: 0) 262128 262144 14464 0.00 0.00 42.37 66.15 0 0 (Gen: 0) 262128 262144 1656 0.00 0.00 42.37 66.16 0 0 (Gen: 0) .... and was interrupted ........... 1,614,769,480 bytes allocated in the heap 78,801,952 bytes copied during GC 25,624 bytes maximum residency (6160 sample(s)) 6160 collections in generation 0 ( 10.35s) 1 Mb total memory in use INIT time 0.01s ( 0.00s elapsed) MUT time 32.01s ( 55.38s elapsed) GC time 10.35s ( 10.78s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 42.37s ( 66.16s elapsed) %GC time 24.4% (16.3% elapsed) Alloc rate 50,430,027 bytes per MUT second Productivity 75.5% of total user, 48.4% of total elapsed So, what could be the reason of such memory leak? What else may grow if the heap remains constant? How can it be observed? Any ideas are welcome. -- Dimitry Golubovsky Anywhere on the Web

Dimitry Golubovsky wrote:
I wrote a very simple Fudgets program (just copies stdin to stdout, no graphics involved)
-------- leaktest.hs ------------------
module Main where
import Graphics.UI.Fudgets.Fudgets
main = fudlogue (stdoutF >==< stdinF)
and ran it like this:
yes | leaktest
I found out that the program grows in memory. Its "traditional" analog:
-------- leaktest2.hs -----------------
module Main where
import System.IO
main = do hGetLine stdin >>= hPutStrLn stdout main
works in constant space.
I tried to observe the GC realtime stats with +RTS -Sstderr -M600K
It turns out, garbage is collected, number of allocated and collected bytes are mostly constant, and number of live bytes fluctuates, but averagely stays the same:
Alloc Collect Live GC GC TOT TOT Page Flts bytes bytes bytes user elap user elap 316720 262144 9528 0.00 0.00 0.02 0.02 144 499 (Gen: 0) 262128 262144 22188 0.01 0.01 0.03 0.04 0 3 (Gen: 0) 262128 262144 8276 0.00 0.00 0.04 0.05 0 0 (Gen: 0) 262128 262144 24612 0.01 0.01 0.05 0.06 0 0 (Gen: 0) 262128 262144 10680 0.00 0.00 0.06 0.07 0 0 (Gen: 0) 262128 262144 23376 0.00 0.00 0.06 0.08 0 0 (Gen: 0) 262128 262144 9444 0.00 0.00 0.07 0.09 0 0 (Gen: 0) 262012 262144 25492 0.00 0.00 0.07 0.10 0 0 (Gen: 0)
... program grows to 10M .........
262128 262144 1684 0.01 0.01 42.33 66.10 0 0 (Gen: 0) 262128 262144 13396 0.01 0.01 42.34 66.11 0 0 (Gen: 0) 262124 262144 25540 0.01 0.01 42.35 66.12 0 0 (Gen: 0) 262128 262144 11988 0.00 0.00 42.35 66.13 0 0 (Gen: 0) 262128 262144 1760 0.00 0.00 42.36 66.14 0 0 (Gen: 0) 262128 262144 14464 0.00 0.00 42.37 66.15 0 0 (Gen: 0) 262128 262144 1656 0.00 0.00 42.37 66.16 0 0 (Gen: 0)
.... and was interrupted ...........
1,614,769,480 bytes allocated in the heap 78,801,952 bytes copied during GC 25,624 bytes maximum residency (6160 sample(s))
6160 collections in generation 0 ( 10.35s)
1 Mb total memory in use
INIT time 0.01s ( 0.00s elapsed) MUT time 32.01s ( 55.38s elapsed) GC time 10.35s ( 10.78s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 42.37s ( 66.16s elapsed)
%GC time 24.4% (16.3% elapsed)
Alloc rate 50,430,027 bytes per MUT second
Productivity 75.5% of total user, 48.4% of total elapsed
So, what could be the reason of such memory leak? What else may grow if the heap remains constant? How can it be observed?
Any ideas are welcome.
This may help a little: http://www.haskell.org/ghc/dist/current/docs/users_guide/prof-heap.html#mem-... basically the extra memory is either mmap()'d or malloc()'d, probably by some code in your program or a library it uses (there's a small possibility that it might be the GHC runtime, but that's unlikely). You should use some other memory debugging tools, like a debugging malloc() library. Cheers, Simon

Hi, I found and fixed this space leak in the Fudget library (it was a malloc without free). Thomas H Simon Marlow wrote:
Dimitry Golubovsky wrote:
I wrote a very simple Fudgets program (just copies stdin to stdout, no graphics involved)
I found out that the program grows in memory.
basically the extra memory is either mmap()'d or malloc()'d, probably by some code in your program or a library it uses
participants (3)
-
Dimitry Golubovsky
-
Simon Marlow
-
Thomas Hallgren