Sponsored Link •
|
Advertisement
|
The Heap of Fish applet, shown in Figures 9-2 through 9-5, demonstrates a compacting, mark and sweep, garbage-collected heap. To facilitate compaction, this heap uses indirect handles to objects instead of direct references. It is called Heap of Fish because the only type of objects stored on the heap for this demonstration are fish objects, defined as follows:
// On CD-ROM in file gc/ex1/YellowFish.java class YellowFish { YellowFish myFriend; } // On CD-ROM in file gc/ex1/BlueFish.java class BlueFish { BlueFish myFriend; YellowFish myLunch; } // On CD-ROM in file gc/ex1/RedFish.java class RedFish { RedFish myFriend; BlueFish myLunch; YellowFish mySnack; }
As you can see, there are three classes of fish: red, yellow, and blue. The red fish is the largest as it has three instance variables. The yellow fish, with only one instance variable, is the smallest fish. The blue fish has two instance variables and is therefore medium-sized.
The instance variables of fish objects are references to other fish objects. BlueFish.myLunch
, for example, is a reference to a YellowFish
object. In this implementation of a garbage-collected heap, a reference to an object occupies four bytes. Therefore, the size of the instance data of a RedFish
object is twelve bytes, a BlueFish
object is eight bytes, and a YellowFish
object is four bytes.
Heap of Fish has five modes, which can be selected via radio buttons at the bottom left of the applet. When the applet starts it is in swim mode. Swim mode is just a gratuitous animation, vaguely reminiscent of the familiar image of a big fish about to eat a medium-sized fish, which is about to eat a small fish. The other four modes--allocate fish, assign references, garbage collect, and compact heap--allow you to interact with the heap. In the allocate fish mode, you can instantiate new fish objects. In the assign references mode, you can build a network of local variables and fish that refer to other fish. In garbage collect mode, a mark and sweep operation will free any unreferenced fish. The compact heap mode allows you to slide heap objects so that they are side by side at one end of the heap, leaving all free memory as one large contiguous block at the other end of the heap.
The allocate fish mode, shown in Figure 9-6, allows you to allocate new fish objects on the heap. In this mode you can see the two parts that make up the heap: the object pool and handle pool. The object pool is a contiguous block of memory from which space is taken for new objects. It is structured as a series of memory blocks. Each memory block has a four-byte header that indicates the length of the memory block and whether or not it is free. The headers are shown in the applet as black horizontal lines in the object pool.
The object pool in Heap of Fish is implemented as an array of int
s. The first header is always at objectPool[0]
. The object pool's series of memory blocks can be traversed by hopping from header to header. Each header gives the length of its memory block, which also reveals where the next header is going to be. The header of the next memory block will be the first int
immediately following the current memory block.
When a new object is allocated, the object pool is traversed until a memory block is encountered with enough space to accommodate the new object. Allocated objects in the object pool are shown as colored bars. YellowFish
objects are shown in yellow, BlueFish
in blue, and in red. Free memory blocks, those that currently contain no fish, are shown in white.
The handle pool in Heap of Fish is implemented as an array of objects of a class named ObjectHandle
. An ObjectHandle
contains information about an object, including the vital index into the object pool array. The object pool index functions as a reference to the object's instance data in the object pool. The ObjectHandle
also reveals information about the class of the fish object. As mentioned in Chapter 5, "The Java Virtual Machine," every object on the heap must in some way be associated with its class information stored in the method area. In Heap of Fish, the ObjectHandle
associates each allocated object with information such as its class--whether it is a RedFish
, BlueFish
, or YellowFish
--and some data used in displaying the fish in the applet user interface.
The handle pool exists to make it easier to defragment the object pool through compaction. References to objects, which can be stored in local variables of a stack or the instance variables of other objects, are not direct indexes into the object pool array. They are instead indexes into the handle pool array. When objects in the object pool are moved for compaction, only the corresponding ObjectHandle
must be updated with the object's new object pool array index.
Each handle in the handle pool that refers to a fish object is shown as a horizontal bar painted the same color as the fish to which it refers. A line connects each handle to its fish instance variables in the object pool. Those handles that are not currently in use are drawn in white.
The assign references mode, shown in Figure 9-7, allows you to build a network of references between local variables and allocated fish objects. A reference is merely a local or instance variable that contains a valid object reference. There are three local variables which serve as the roots of garbage collection, one for each class of fish. If you do not link any fish to local variables, then all fish will be considered unreachable and freed by the garbage collector.
The assign references mode has three sub-modes: move fish, link fish, and unlink fish. You can select the sub-mode via radio buttons at the bottom of the canvas upon which the fish appear. In move fish mode, you can click on a fish and drag it to a new position. You might want to do this to make your links more visible or just because you feel like rearranging fish in the sea.
In link fish mode, you can click on a fish or local variable and drag a link to another fish. The fish or local variable you initially drag from will be assigned a reference to the fish you ultimately drop upon. A line will be shown connecting the two items. A line connecting two fish will be drawn between the nose of the fish with the reference to the tail of the referenced fish.
Class YellowFish
has only one instance variable, myFriend
, which is a reference to a YellowFish
object. Therefore, a yellow fish can only be linked to one other yellow fish. When you link two yellow fish, the myFriend
variable of the "dragged from" fish will be assigned the reference to the "dropped upon" fish. If this action were implemented in Java code, it might look like:
// Fish are allocated somewhere YellowFish draggedFromFish = new YellowFish(); YellowFish droppedUponFish = new YellowFish(); // Sometime later the assignment takes place draggedFromFish.myFriend = droppedUponFish;
Class BlueFish
has two instance variables, BlueFish myFriend
and YellowFish myLunch
. Therefore, a blue fish can be linked to one blue fish and one yellow fish. Class RedFish
has three instance variables, RedFish myFriend
, BlueFish myLunch
, and YellowFish mySnack
. Red fish can therefore link to one instance of each class of fish.
In unlink fish mode, you can disconnect fish by moving the cursor over the line connecting two fish. When the cursor is over the line, the line will turn black. If you click a black line the reference will be set to null and the line will disappear.
The garbage collect mode, shown in Figure 9-8, allows you to drive the mark and sweep algorithm. The Step button at the bottom of the canvas takes you through the garbage collection process one step at a time. You can reset the garbage collector at any time by clicking the Reset button. However, once the garbage collector has swept, the freed fish are gone forever. No manner of frantic clicking of the Reset button will bring them back.
The garbage collection process is divided into a mark phase and a sweep phase. During the mark phase, the fish objects on the heap are traversed depth-first starting from the local variables. During the sweep phase, all unmarked fish objects are freed.
At the start of the mark phase, all local variables, fish, and links are shown in white. Each press of the Step button advances the depth-first traversal one more node. The current node of the traversal, either a local variable or a fish, is shown in magenta. As the garbage collector traverses down a branch, fish along the branch are changed from white to gray. Gray indicates the fish has been reached by the traversal, but there may yet be fish further down the branch that have not been reached. Once the terminal node of a branch is reached, the color of the terminal fish is changed to black and the traversal retreats back up the branch. Once all links below a fish have been marked black, that fish is marked black and the traversal returns back the way it came.
At the end of the mark phase, all reachable fish are colored black and any unreachable fish are colored white. The sweep phase then frees the memory occupied by the white fish.
The compact heap mode, shown in Figure 9-9, allows you to move one object at a time to one end of the object pool. Each press of the Slide button will move one object. You can see that only the object instance data in the object pool moves; the handle in the handle pool does not move.
The Heap of Fish applet allows you to allocate new fish objects, link fish, garbage collect, and compact the heap. These activities can be done in any order as much as you please. By playing around with this applet you should be able to get a good idea how a mark and sweep garbage-collected heap works. There is some text at the bottom of the applet that should help you as you go along. Happy clicking.
The CD-ROM contains the source code examples from this chapter in the gc directory. The Heap of Fish applet is contained in a web page on the CD-ROM in file applets/HeapOfFish.html
. The source code for this applet is found alongside its class files, in the applets/HeapOfFish
directory.
For more information about the material presented in this chapter, visit the resources page: http://www.artima.com/insidejvm/resources/
.
Sponsored Links
|