[MLton] space safety for structures

Stephen Weeks MLton@mlton.org
Fri, 2 Jul 2004 17:12:21 -0700

To test my model, I fed the following program to SML/NJ.

structure A =
      val n = 100
      val n = Array.maxLen
      val a = Array.array (n, 13)
      val x = 0
; (* The semicolon is important so that F and A are compiled separately. *)
functor F () =
      val _ = print (concat ["F ", Int.toString A.x, "\n"])
structure A = struct end
val _ = SMLofNJ.exportML "z"

As it stands, this produces a 77,696,284 byte heap.  On the other
hand, if I swap the definitions of A.n, so that that A.a is only 100
elements, then the heap is 10,595,540 bytes.  The difference between
those sizes is is 67,100,744, which is quite close to 4 *
Array.maxLen.  So, SML/NJ is clearly keeping A.a alive, even though it
is dead.  I conjecture this is because SML/NJ represents F as a
closure that refers to the representation of A as a tuple, not as a
closure that refers to the individual elements of A that F uses.