Version française
Home     About     Download     Resources     Contact us    
Browse thread
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Ohad Rodeh <orodeh@c...>
Subject:


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.