Hi Matthew,<br><br><div class="gmail_quote">On Fri, Apr 15, 2011 at 4:12 AM, Matthew Fluet <span dir="ltr"><<a href="mailto:matthew.fluet@gmail.com">matthew.fluet@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On Thu, Apr 14, 2011 at 10:03 AM, Ivan Tomac <<a href="mailto:ivan.tomac@gmail.com">ivan.tomac@gmail.com</a>> wrote:<br>
> Why does the following code (taken from regression/weak.2.sml) return true,<br>
> and more importantly why is it supposed to return true (according to the<br>
> expected test result in weak.2.ok):<br>
><br>
> structure Weak = MLton.Weak<br>
><br>
> val x = (13, ref 5)<br>
> val wx = Weak.new x<br>
> fun isAlive () = isSome (Weak.get wx)<br>
> val _ = MLton.GC.collect ()<br>
> val _ = print (Bool.toString (isAlive ()) ^ "\n")<br>
><br>
> Shouldn't x be garbage collected?<br>
<br>
</div>In this program, the object bound to x can be made global (with only<br>
constant space overhead), and hence it is reachable throughout the<br>
lifetime of the whole program. This is a space/time tradeoff ---<br>
making such small objects global may waste a little space (because<br>
they are not garbage collected), but can be efficiently accessed<br>
through their global name (rather than threading their pointers<br>
through the program in variables and closures).<br>
<br></blockquote><div><br>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?<br><br>
<br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Two slight variations on the program will prevent x from being<br>
globalized and lead to the object being garbage collected.<br>
<br>
One: make the object bound to x a "large" (technically, not manifestly<br>
small) object:<br>
<br>
val x = (13, ref (List.tabulate (100, fn i => i)))<br>
<div class="im">val wx = Weak.new x<br>
fun isAlive () = isSome (Weak.get wx)<br>
val _ = MLton.GC.collect ()<br>
val _ = print (Bool.toString (isAlive ()) ^ "\n")<br>
<br>
</div>Two: bind a (mutable) object to x more than once:<br>
<br>
fun f _ = let<br>
<div class="im">val x = (13, ref 5)<br>
</div><div class="im">val wx = Weak.new x<br>
fun isAlive () = isSome (Weak.get wx)<br>
val _ = MLton.GC.collect ()<br>
val _ = print (Bool.toString (isAlive ()) ^ "\n")<br>
</div>in () end<br>
val _ = List.app f (List.tabulate (10, fn i => i))<br>
<br>
Both of these programs will print "false".<br>
<div class="im"><br></div></blockquote><div><br>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?<br>
<br>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?<br><br>Ivan<br></div></div>