System Software Assignment 6 — Living with a garbage collector

Exercise 1: in the .NET system

1. Why Finalize-methods are not directly executed by the garbage collector? Finalizers can, in principle, contain code which takes a lot of time to execute or worse code that could block. Making the garbage collector execute the finalizers of the disposed objects could significantly hurt performance or bring to a complete system halt. 2. Suppose that someone wants to recycle objects after use and for this purpose resuscitates dead objects in their finalizer appending them at the end of an object pool. In the following example when objects of the class Test are collected they are resuscitated by the finalizer which puts them in a reachable structure (Pool).

public class Test {

protected override void Finalize() {

/* we add the instance (this) to a globally * * reachable structure */

Pool.Add(this);

}

}

Explain why this will not work without any additional support of the finalize mechanism. The finalizer is called only once for a given object and the second time the object dies it will not be resuscitated. The reason lies in the fact that after running the finalizer, the entry in the finalization queue for this object is deleted. To avoid this the user can re-insert the object in the finalization queue with the ReRegisterForFinalize call. 3. The execution order of the Finalize method of all the participants (objects in the freachable list) is not specified. Discuss why this could be a problem and propose a solution. Suppose that there are two objects o1 and o2 in the finalization queue and that these objects have references to each other and that these references are used in the Finalize method. The finalizer thread starts deletes the object o1 and executes the finalizer of o2: at this point in time there will be a null reference since the object was already removed. For this reason programmers should avoid to reference other objects in the finalizers and provide some Close or Dispose methods to clean up objects.

1 Exercise 2: Generations

Generational garbage collectors rely on write barriers to detect pointers to a younger generation. The simplest write barrier implementation involves the generation of instrumented code by the compiler: before writing a pointer the compiler inserts a conditional check to detect the presence of a barrier. Describe an alternative, and more efficient, implementation of a write barrier.

One well known approach is to divide the heap into cards of size 2k words (typically, k = 5). Let then every card have an associated bit in a separate bit vector. A store check simply marks the bit corresponding to the location being updated. At garbage collection time, the collector scans the bit vector and, whenever it finds a marked bit, examines all pointers in the corresponding card in the heap. st [%obj + offset], %ptr store ptr into object's field add %obj, offset, %temp calculate address of updated word sll %temp, k, %temp divide by card size 2k (shift left) st %g0, [%byte_map + %temp] clear byte in byte map

For some stores, the compiler can statically know that no store check is necessary, for example, when storing an integer (assuming that integers are implemented as immediates rather than as real heap- allocated objects).

2 Exercise 3: Weak pointers

Weak pointers are references to objects which allow the reference object to be destroyed by the garbage collector. In .NET if a user wants to follow this pointers he has to check if the reference is still valid. On other systems like Java and Python the object with a weak reference can be notified of the deletion of the referenced structure. Give some examples on how weak pointers could be used for .NET and Java. Which are the advantages and disadvantages of both systems?

• On systems like .NET weak pointers are used to link large structures which can be easily recon- structed. One example is a cache of a file system’s hierarchy: if there is enough free memory the structure is kept and can be used but the garbage collector is allowed to remove it if some space is needed.

• On systems with notification weak references can be used to keep an eye on certain structures: we can link objects without prohibiting their collection and we can be notified when they are removed.

References 1 Jeffrey Richter, Garbage Collection: Automatic in the Microsoft .NET Framework, MSDN Magazine, November 2000, http://www.cs.inf.ethz.ch/edu/37-201/files/GC in NET.pdf

2 Paul Wilson, Uniprocessor garbage collection techniques, Proceedings of the Memory Man- agement International Workshop, Saint-Malo, France, Sep 1992, ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps

3