[MLton-user] Weak pointer regression test 2

Ivan Tomac ivan.tomac at gmail.com
Fri Apr 15 04:06:24 PDT 2011


Hi Matthew,

On Fri, Apr 15, 2011 at 4:12 AM, Matthew Fluet <matthew.fluet at gmail.com>wrote:

> On Thu, Apr 14, 2011 at 10:03 AM, Ivan Tomac <ivan.tomac at gmail.com> wrote:
> > Why does the following code (taken from regression/weak.2.sml) return
> true,
> > and more importantly why is it supposed to return true (according to the
> > expected test result in weak.2.ok):
> >
> > structure Weak = MLton.Weak
> >
> > val x = (13, ref 5)
> > val wx = Weak.new x
> > fun isAlive () = isSome (Weak.get wx)
> > val _ = MLton.GC.collect ()
> > val _ = print (Bool.toString (isAlive ()) ^ "\n")
> >
> > Shouldn't x be garbage collected?
>
> In this program, the object bound to x can be made global (with only
> constant space overhead), and hence it is reachable throughout the
> lifetime of the whole program.  This is a space/time tradeoff ---
> making such small objects global may waste a little space (because
> they are not garbage collected), but can be efficiently accessed
> through their global name (rather than threading their pointers
> through the program in variables and closures).
>
>
Thanks for the clarification. So if I'm understanding that right, in this
instance x is still allocated on the heap but available throughout the
lifetime of the program?



> Two slight variations on the program will prevent x from being
> globalized and lead to the object being garbage collected.
>
> One: make the object bound to x a "large" (technically, not manifestly
> small) object:
>
> val x = (13, ref (List.tabulate (100, fn i => i)))
> val wx = Weak.new x
> fun isAlive () = isSome (Weak.get wx)
> val _ = MLton.GC.collect ()
> val _ = print (Bool.toString (isAlive ()) ^ "\n")
>
> Two: bind a (mutable) object to x more than once:
>
> fun f _ = let
> val x = (13, ref 5)
> val wx = Weak.new x
> fun isAlive () = isSome (Weak.get wx)
> val _ = MLton.GC.collect ()
> val _ = print (Bool.toString (isAlive ()) ^ "\n")
> in () end
> val _ = List.app f (List.tabulate (10, fn i => i))
>
> Both of these programs will print "false".
>
>
Interesting. Would you know by any chance if there is a document somewhere
mentioning what structures and cases does MLton optimize so that they're
either globalized or not allocated on the heap in first place?

I'm a bit confused about just when is it safe to attach a weak pointer to
something. For the purpose of finalizing things allocated in a foreign
library, what kind of a data structure would I have to wrap the allocated
resource in, so that when a weak pointer is attached I have a reliable way
of telling when the structure is no longer reachable?

Ivan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mlton.org/pipermail/mlton-user/attachments/20110415/90e89559/attachment.htm


More information about the MLton-user mailing list