It would be very useful in Suneido to have a way to automatically release resources such as Windows "handles" and open files. Suneido's garbage collection will automatically release the memory but it doesn't know anything about resources. Currently, programs must explicitly release their resources when they're finished with them e.g. close files. In user interface code this is often done in response to the WM_DESTROY message. But in other places e.g. report formats, there is no obvious place to do this. It can be especially hard to ensure that resources are released in the event of exceptions (errors). It's really the same kind of problem that garbage collection solves for releasing memory.
Initially, I thought the way to do this would be to support "finalization" methods in Suneido. But after looking into it further, I think a better approach is to add "weak references" to Suneido, and to use them to release resources. My current feeling is that this is something that should be added to Suneido in the near future.
The garbage collector calls finalization methods after determining an object is no longer referenced, but prior to free'ing it. Finalization methods can release resources such as file handles that are used by the object. Java has finalization. It seems like a simple, obvious solution. However, there are a number of subtle problems with finalization. One problem is that the order of finalization is not predictable. Another problem is that it is possible for finalization methods to "resurrect" an object by storing a reference to it. This in turn "resurrects" any objects that this one references. But these other objects may already have been finalized! There are ways to work around these issues, but obviously it's not as simple as it might seem.
"Weak references" are another memory management facility. A weak reference stores a reference so a memory object in a way that doesn't stop the object from being free'd by garbage collection. At the end of garbage collection, any weak references that refer to objects that are now free'd are cleared. This might work as follows:
wr = WeakReference(value) wr.Get() => value // value is still "live" // some time later wr.Get() => False // value has been free'd
Weak references are a more primitive mechanism; they are simpler to implement and do not have the same problems as finalization.
The key idea is that you can use weak references to implement a scheme to automatically release resources. The basic method is:
- When you allocate a resource, you add it to a
- The table contains an entry for each resource,
including a weak reference
to the object using the resource, and information about how
to release the
resource (e.g. the handle value and a "release" function)
- Periodically (possibly by a background thread) the table is scanned for entries whose weak reference has been cleared. Using the information in the entry, the resource is released, and the entry is then removed from the table.
One enhancement is to have the garbage collector add cleared weak references to a queue. You can then eliminate the linear scan of the resource table by keying it on the weak reference.
A form of weak references can also be used to reference memory objects that can be free'd if memory space is required, for example, a cached copy of an external file. Java calls these "soft references". The garbage collector treats these references slightly differently in that it only free's the objects if memory space is running low.
For more information on weak references in Java see: Java finalization