caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Thomas Fischbacher <t.fischbacher@soton.ac.uk>
To: OCaML Mailing List <caml-list@inria.fr>
Subject: [Caml-list] Weird GC behaviour
Date: Tue, 27 Sep 2011 18:30:44 +0100	[thread overview]
Message-ID: <4E820844.7050705@soton.ac.uk> (raw)


Dear Camels,

The example below shows GC behaviour which in my view is somewhat
weird: I am building two very similar sorts of hash tables that map
variant types to strings. The parameter "works" (which gets passed
through from the "demo" to the "setup" function) allows one to choose,
when calling the script, whether it behaves properly or shows weird
behaviour.

For Rtag, inlining get_rtag does not make a difference, but for Ftag,
inlining the get_ftag call breaks things both with the interpreter and
compiler, but in different ways.

So... my question is: is there a documented reliable way to avoid this
sort of funny behaviour?!?

=================================
type funny_tag = Ftag of string;;

type funny_ref = Rtag of string ref;;

let get_ftag s = Ftag s;;

let get_rtag s = Rtag (ref s);;

let fin_str ht k =
   let Ftag s = k in
   let () = Printf.printf "Removing str '%s'\n%!" s in
   Hashtbl.remove ht k
;;

let fin_ref ht k =
   let Rtag rs = k in
   let () = Printf.printf "Removing ref '%s'\n%!" !rs in
   Hashtbl.remove ht k
;;


let setup works =
   let ht_str = Hashtbl.create 17 in
   let ht_ref = Hashtbl.create 17 in
   let (funny_str, funny_ref) =
   if works
     then (get_ftag "funny",get_rtag "funny")
     else (Ftag "funny", Rtag (ref "funny"))
   in
   (* Note that they keys used below are equal but not identical to the 
entities above *)
   let () = Hashtbl.add ht_str (Ftag "funny") "situation" in
   let () = Hashtbl.add ht_ref (Rtag (ref "funny")) "situation" in
   let () = Gc.finalise (fin_str ht_str) funny_str in
   let () = Gc.finalise (fin_ref ht_ref) funny_ref in
   ((ht_str,ht_ref),(funny_str,funny_ref))
;;

let left (p,q) = p;;

let demo works =
   let (ht_str,ht_ref) = left (setup works) in
   (* Note that I drop the references on the keys that have finalizers 
registered. *)
   let () = Gc.full_major () in
   let () = Gc.compact () in
   Printf.printf "ht_str entries: %d ht_ref entries: %d\n%!" 
(Hashtbl.length ht_str) (Hashtbl.length ht_ref)
;;

let () = demo (Array.length Sys.argv > 1 && Sys.argv.(1) = "magic");;


(* === Behaviour ===

$ ocaml gc_bug.ml
Removing ref 'funny'
ht_str entries: 1 ht_ref entries: 0

$ ocaml gc_bug.ml magic
Removing ref 'funny'
Removing str 'funny'
ht_str entries: 0 ht_ref entries: 0

$ ocamlopt -o gc_bug gc_bug.ml

$ ./gc_bug
Fatal error: exception Invalid_argument("Gc.finalise")

$ ./gc_bug magic
Removing ref 'funny'
Removing str 'funny'
ht_str entries: 0 ht_ref entries: 0

$ ocaml
         Objective Caml version 3.12.0

#

$ uname -prs
FreeBSD 9.0-BETA3 amd64

============ *)

=================================

-- 
best regards,
Thomas Fischbacher
t.fischbacher@soton.ac.uk

             reply	other threads:[~2011-09-27 17:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-27 17:30 Thomas Fischbacher [this message]
2011-09-28 11:19 ` Damien Doligez
2011-09-28 11:53   ` Thomas Fischbacher
2011-09-28 12:12     ` Gabriel Scherer
2011-09-28 13:07     ` John Carr
2011-09-28 15:30     ` Damien Doligez
2011-09-28 23:32       ` Philippe Wang

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=4E820844.7050705@soton.ac.uk \
    --to=t.fischbacher@soton.ac.uk \
    --cc=caml-list@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).