WEAK
signature
A weak pointer is one that is not sufficient to keep an object live. If some object x
is pointed to by ordinary pointers and by weak pointers, it will stay live (not be garbage collected); but if it is pointed to only by weak pointers, then it may be garbage collected.
As an example, suppose we want to make a "finalization" function for some data structure t
. We can create a w=weak(t)
and put w
onto a list (of things we want to finalize). Then we can watch this list from time to time, and when strong(w)=NONE
we can perform the finalization procedure. A good time to examine the list is upon receipt of the GC
signal; see Signals.
The semantics of weak pointers to immutable data structures in ML is ambiguous. For example, consider the following:
let val (b',w') = let val a = (1,2) val b = (1,2) val w = weak(a) in (b,w) end in (b, strong w) endAfter this expression is evaluated,
a
is both statically and dynamically dead; so one would think that the result is ((1,2),NONE)
. But first of all, weak pointers do not generally go dead until a garbage collection occurs, so the answer will likely be ((1,2),SOME(1,2))
. Secondly, the compiler or runtime system may have done common subexpression elimination, so that a
and b
point to the same (1,2), and therefore w
's contents may stay alive as long as b
does.
Finally, in this example:
let val a = (1,2) val w = weak(a) in (a,w) endeven though
a
is still alive, the compiler may have unpacked a
into registers; in creating w
it may box a new copy of (1,2) onto the heap, but there are no other pointers to this copy, so w
's contents are immediately dead and may be reclaimed by the collector.
One way of avoiding these problems, this year, is to apply weak
only to ref
objects, which have a stronger notion of object identity than do ordinary records, tuples, and data constructors. This works as long as the compiler does not optimize ref
s too much, which at present is a safe assumption.
signature WEAK
structure SMLofNJ.Weak
: WEAK
type 'a weak
val weak : 'a -> 'a weak
val strong : 'a weak -> 'a option
type weak'
val weak' : 'a -> weak'
val strong' : weak' -> bool
type 'a weak
'a
.
weak a
strong w
NONE
if the object to which w points has already been garbage-collected; or SOME(a)
if w points to some still-live object a
.
type weak'
'a
; weak pointers of this type can be examined to see if the underlying objects are still alive, but the underlying objects cannot be extracted from them. This is useful to make finalizers (of heterogenous collections) statically type-check.
weak' a
strong' w