From: "Björn Pelzer" <bpelzer@uni-koblenz.de>
To: caml-list@yquem.inria.fr
Subject: Understanding GC and Alarms
Date: Tue, 04 Aug 2009 15:39:25 +0200 [thread overview]
Message-ID: <4A783A0D.5080906@uni-koblenz.de> (raw)
Hello,
I'm new to this list and fairly new to OCaml. First I posted this on the
beginner's list, but I was recommended to try it here, so here we go. :-)
Right now I'm having some problems with the garbage collector and the
Gc.alarm - this combination shows some (to me) odd behaviours which are
not detailed in the reference manual. Maybe someone could shed some
light on this?
Basically, at the end of a major GC cycle the GC calls the user
functions defined for any alarms. This I understand, and for the most
part it works as I expect it.
The first oddity is that I can define an alarm function which starts
another GC cycle (by calling Gc.full_major). This results, quite
understandably, in an infinite loop - GC calls alarm calls GC calls
alarm....
However, it seems that the GC no longer works quite the same when called
from within an alarm, as it no longer calls any finalisation functions.
Normally (outside alarms) the GC will print "Calling finalisation
functions. Done calling finalisation functions." if I do a Gc.full_major
and the verbosity is set appropriately. With the alarm loop, the GC will
only print the first part ("Calling finalisation functions.") once at
the start of the loop and then begin looping, starting new cycles but no
new finalisations. If I limit the looping with a counter, the GC will
behave normally again in future GC cycles outside the alarm. So it seems
the alarm or the finalising put the GC into a special mode where it no
longer does everything in a cycle that it would usually do.(?)
The other (and to me more severe) oddity is that if the alarm function
raises an exception, then the GC seems to remain in its "special mode"
where it starts no finalisation calling - but now it will also refuse to
do any alarms.
The latter is a bit of a problem for me right now, as I was using a
Gc.alarm to implement a check for a memory limit: if the alarm function
at the end of a GC cycle finds the memory usage to be above the limit,
an exception is raised which interrupts the normal operation of the
program, and the program waits for instructions from stdin.
As the first such exception-from-an-alarm effectively breaks future
alarm handling, this only works once. This was not noticeable in earlier
versions of the program which were single-use only - the alarm exception
would halt the program and say sorry, out of memory. The new program
version is supposed to be user-interactive, though, so it must be able
to catch multiple memory excesses. Worse, it also uses Unix.ITIMER_REAL
induced timer exceptions to limit processing time. Potentially such a
timer exception could also interrupt an alarm check, again breaking the
alarm handling.
Is there a way to get the GC back to normal after an exception during
the alarm? Right now it seems I have to drop alarm usage entirely, and
instead put explicit memory checks into all sorts of strategic places
throughout the program, which is not all that elegant.
Here is a short program which shows what I mean. I'm probably just
making some stupid mistake?
exception Ex
let main () =
let cnt = ref 0
in
(Gc.set {(Gc.get()) with Gc.verbose = 0x081});
let alarm_function () =
(print_endline "Alarm!";
cnt := !cnt + 1;
(* do 3 loop iterations *)
if !cnt < 3 then
(Gc.full_major ())
(* after the 3rd iteration, exit loop with an exception *)
else
(raise Ex))
in
ignore (Gc.create_alarm alarm_function);
try
(* this will call the alarm and start the loop *)
(Gc.full_major ())
with
| Ex ->
(print_endline "Exception raised!";
(* new GC cycle calls no alarm after the exception :-( *)
Gc.full_major ())
let () = main ();;
Thank you for your time,
Björn
--
Björn Pelzer
AGKI - Artificial Intelligence Research Group
University Koblenz-Landau, B 225
http://www.uni-koblenz.de/~bpelzer
Tel.(office): (+49) 261 287 2776
Tel.(home): (+49) 261 942 3908
next reply other threads:[~2009-08-04 13:39 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-04 13:39 Björn Pelzer [this message]
2009-08-05 14:33 ` [Caml-list] " Damien Doligez
2009-08-05 15:04 ` Björn Pelzer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A783A0D.5080906@uni-koblenz.de \
--to=bpelzer@uni-koblenz.de \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).