Garbage collection qustion

From: Ohad Rodeh (orodeh@cs.huji.ac.il)
Date: Tue Jun 30 1998 - 12:17:16 MET DST


Date: Tue, 30 Jun 1998 13:17:16 +0300 (IDT)
From: Ohad Rodeh <orodeh@cs.huji.ac.il>
To: Ocaml Mailing List <caml-list@inria.fr>

On Mon, 29 Jun 1998 hayden@pa.dec.com wrote:

>
> Ohad,
> My suspicion is that what you are seeing is the result
> of fragmentation. The 10000byte strings all need to be
> allocated directly from the major heap. When they get
> released, smaller objects may then be allocated in parts
> of the 10K block,so that the next time you want a 10K
> block, there may only be 9998byte blocks, so it keeps on
> growing memory to get fresh 10K blocks.
> Try running (Gc.compact ()) every so often. I think that
> will prevent the heap from continuing to grow. Tell me
> what happens.
>
> --Mark
>
> > Hi,
> > I have a problem with the Ocaml garbage collector. The included program
> > allocates memory from the heap and does nothing with it. The heap keeps
> > growing without bound although memory is not being used and no refrences
> > to it exist.
> >
> > Running the program with the following parameters:
> > ttt -nrounds 1000 -status 3 -chunk 10000
> >
> > Will go through 1000 rounds of allocating a string of size 10000. The
> > status flag describes how many GC status reports you would like.
> >
> > Why does the heap grow without bound?
> > Ohad.
> > -------------------------------
> >
> > (*ttt.ml
> > *)
> > open Printf
> >
> > let nrounds = ref 100
> > let status = ref 10
> > let chunk = ref 1000
> >
> > (* Status of the heap
> > *)
> > let string_list_of_gc_stat s =
> > let alloc_promote_pct = (s.Gc.promoted_words * 100) / s.Gc.minor_words in
> > let alloc_major_direct = s.Gc.major_words - s.Gc.promoted_words in
> > let blocks_total = s.Gc.live_blocks + s.Gc.free_blocks in
> > let blocks_live_pct = (s.Gc.live_blocks * 100) / blocks_total in
> > let words_live_pct = (s.Gc.live_words * 100) / s.Gc.heap_words in
> > [ sprintf "allocation: minor=%.1fM (%d%% promoted) (direct major=%dK)"
> > ((float s.Gc.minor_words) /. 1000000.0) alloc_promote_pct (alloc_major_direct/1000) ;
> > sprintf "collections: minor=%d, major=%d, compact=%d" s.Gc.minor_collections s.Gc.major_collections s.Gc.compactions ;
> > sprintf "words: %d (%d%% live) (%d chunks)" s.Gc.heap_words words_live_pct s.Gc.heap_chunks;
> > sprintf "blocks: %d (%d%% live) (largest_free=%d)" blocks_total blocks_live_pct s.Gc.largest_free
> > ]
> >
> > let string_of_list f l = sprintf "[%s]" (String.concat "|" (List.map f l))
> >
> > (* Print the heap status?
> > *)
> > let chp i =
> > if (i mod (!nrounds / !status) = 0) then (
> > let stat = Gc.stat () in
> > printf "%s\n" (string_of_list (fun x -> x) (string_list_of_gc_stat stat));
> > Gc.minor();
> > Gc.major();
                Gc.compact() (* Added this line now *)
> > )
> >
> > let _ =
> > Arg.parse [
> > "-nrounds",Arg.Int(funi -> nrounds := i), "nrounds";
> > "-status",Arg.Int(fun i -> status := i), "How may heap status reports";
> > "-chunk",Arg.Int(fun i -> chunk := i), "The size of string allocated in each round";
> > ] (fun _ -> ()) "perf-crypto";
> >
> > let r = Gc.get () in
> > r.Gc.verbose <- true;
> > Gc.set r;
> >
> > for i=0 to !nrounds do
> > chp i;
> > let cccc = String.create !chunk in ()
> > done
> >

Thanks,
    for the speedy response. I've added Gc.compact () to the status
reports --- to no avail. The same phenomena occurs with small strings as
well:

ttt -nrounds 100000 -status 3 -chunk 100
<>$<>$<>!Compacting heap...
done.
<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>!Compacting
heap...
done.
<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>!Compacting
heap...
done.
<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>$<>!<>!<>$<>$<>$<>!Compacting
heap...
done.
[allocation: minor=0.0M (4% promoted) (direct major=0K)|collections:
minor=1, major=0, compact=0|words: 63488 (0% live) (1 chunks)|blocks: 120
(99% live) (largest_free=62878)]
[allocation: minor=0.9M (0% promoted) (direct major=0K)|collections:
minor=31, major=7, compact=1|words: 63488 (1% live) (1 chunks)|blocks: 255
(99% live) (largest_free=62343)]
[allocation: minor=1.8M (0% promoted) (direct major=0K)|collections:
minor=61, major=14, compact=2|words: 63488 (1% live) (1 chunks)|blocks:
255 (99% live) (largest_free=62343)]
[allocation: minor=2.7M (0% promoted) (direct major=0K)|collections:
minor=91, major=21, compact=3|words: 63488 (1% live) (1 chunks)|blocks:
255 (99% live) (largest_free=62343)]

        Ohad.



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:14 MET