analytics

Wednesday, October 14, 2009

Garbage Collection



Java manages memory. Therefore, the programmer does not need to allocate memory at the time of object creation. In addition, programmer does not need to free the memory explicitly.

Object creation

Object is constructed either on a memory heap or on a stack.

Memory heap

Generally the objects are created using the new keyword. Some heap memory is allocated to this newly created object. This memory remains allocated throughout the life cycle of the object. When the object is no more referred, the memory allocated to the object is eligible to be back on the heap. The process of releasing such memory back is called as garbage collection.

Stack

During method calls, objects are created for method arguments and method variables. These objects are created on stack.Such objects are eligible for garbage-collection when they go out of scope.



Object creation behind the scene

We learned the syntax of the code for creating a Java object. It is equally interesting to learn what actually happens when you execute such code.
Java environment has a programming memory on which it creates all the objects. When a new object is created, some memory is automatically allocated to it. You (as a programmer) need not bother about the memory allocation issues while creating objects. This is because Java dynamically allocates and frees the memory and this operation is totally transparent to the programmer.
The programming memory is divided into two primary areas:
1. Heap: Whenever an object is created with new, it is created on the memory heap. The heap area is a table of memory units. When the new statement creates a new object, free memory units from this table are allocated for the newly created object. When the object is no more in use and is no more referred by any references, it is not immediately destroyed. It becomes eligible for garbage collection[‡]. Eventually the memory is freed and the object is destroyed.
2. Stack: Stack is also a memory area. When you create object-reference variables and the local variables, they are stored on the stack. They remain on stack as long as they do not go out-of-scope. For instance, the local variables are destroyed as soon as the declaring method or block is exited. Similaraly, object-reference variables are destroyed as soon as they go out-of-scope.
Let us consider the following code to learn more about memory allocation. The code declares some primitives and creates few objects.
int a = 5;
String message = new String("Hello");
Date today = new Date();
char alphabet = ‘c';
Figure 1.6 shows the memory model after the above code is executed. The primitives a and alphabet are stored directly on stack with values. The String object and the Date object are created on the heap and the reference variables for these objects are stored on stack.

Figure 1.6 Memory model after the Java code is executed


Garbage Collection

Garbage Collection is a low-priority thread in java.

Garbage Collection cannot be forced explicitly. JVM may do garbage collection if it is running short of memory. The call System.gc() does NOT force the garbage collection but only suggests that the JVM may make an effort to do garbage collection.

Garbage Collection is hardwired in Java runtime system. Java runtime system keeps the track of memory allocated. Therefore, it is able to determine if memory is still usable by any live thread. If not, then garbage collection thread will eventually release the memory back to the heap.

Garbage Collection usually adopts an algorithm, which gives a fair balance between responsiveness (how quickly garbage-collection thread yields?) and speed of memory recovery (important for memory-intensive operations). Responsiveness is especially important in real time systems.

How does the garbage collector work?

Whenever garbage collector runs, it recycles the memory allocated to the garbage object. In order to do so, it must be able to make a distinction between garbage (or unreachable) objects and reachable objects. The garbage collector uses one of the several algorithms or even a combination of multiple algorithms to do this distinction. You cannot be sure of exactly which algorithms are used in the given JVM as that very much depends on the implementation of JVM.


How an object becomes eligible for Garbage Collection

An object is eligible for garbage collection when no object refers to it.

An object also becomes eligible when its reference is set to null. (Actually all references to the object should be null for it to be eligible.)
For example,

Integer i = new Integer(7);
i = null;

The objects referred by method variables or local variables are eligible for garbage collection when they go out of scope (i.e when the method or their container block exits).



How does an object becomes garbage?

The Java objects are created on the heap. Since the memory on the heap is managed by Java, you never explicitly free the memory. To manage the heap-memory, Java runtime system keeps a track of memory allocation. Therefore, it can somehow (we will see later in GC algorithms) determine which memory is in use and which is not at any given time. Java considers an object as garbage when it can no longer be reached from any reference in the running program. Memory allocated to such object is unusable and must be returned back to the heap. Let us see how an object becomes unreachable with an example. Assume that there is a Car class. Now we will create two objects of this class and make one of them garbage-
1. Car beetle = new Car(); // first Car object created
2. Car bug = new Car(); // second Car object created
3. beetle = bug; // first Car object becomes unreachable
Figure 6.1 shows the memory model after the first two lines are executed. Objects are always allocated memory on heap at the time of their creation. The figure shows two Car objects and two reference variables beetle and bug, are pointing to them respectively.
Figure 6.1 Memory model when two Car objects are created
After the third line in the code (beetle = bug;) is executed, the reference beetle is modified. It now pointes to the Car object created on line 2. Hence, the firstCar object (initially pointed to by beetle ) becomes unreachable because now no reference is pointing it. This unreachable object is of no use for the current program as it cannot access it. Such unreachable object is considered to be a garbage. The memory allocated to it must be released and returned to heap as a free memory. That is exactly what the garbage collector does. It is a part of JVM responsible for releasing the memory allocated to garbage objects. Whenever it runs, it searches for all the garbage objects and recycles the memory allocated to them. Figure 6.2 shows how the reference beetle points to the second Car object making the first Car object unreachable.
Figure 6.2 Memory model after the first Car becomes unreachable in the currently running code.
Figure shows the unreachable Car object with a garbage bag and garbage collector with a truck metaphor. The step, which collects the garbage object, is shown with a question mark (?). It indicates that we do not know exactly when the garbage collector runs and picks the garbage object. But as you can see, the garbage objects are eventually collected and memory is recycled back to the heap.

The garbage object is unreachable to any object reference in the running program, even to the threads (Chapter 12), since Java threads are also objects. In the above example we said that the first Car object was no longer reachable after line 3 because we assumed that only one thread was accessing this piece of code. However, a Java program may have more that one threads running at the same time. In fact, the garbage collector itself runs as a (low-priority) thread in parallel with your program. So, when multiple threads are running, the object is considered as garbage when none of them can reach it. While answering the garbage-collection question, you can safely assume that only one thread is executing the given code unless it is specified otherwise.

Orphaning an object

An object is considered as unreachable when there is no reference, not a single one pointing to it. Whenever you want to make a particular object eligible for garbage collection, you have to make sure that all of its references point to somewhere else.


You can explicitly make an object’s reference null. Then the object reference does not point to the object anymore. If all the object references are made null, the object becomes unreachable. Listing 6.1 creates a Car object and assigns two references to it.
You can see from the listing that the Car object becomes eligible for garbage collection only after both the references to it are made null. When beetle is made null, you can still access the Car object with another reference, bug. Hence the object is reachable. But when bug is also made null, the Car object is unreachable and therefore is eligible for garbage collection.


An object can become unreachable if its sole reference is assigned to point some other object. We have already seen an example of this in section 6.2. In listing 6.2 two Car objects are created. The first Car object’s only reference, beetle, is reassigned to point to the second Car object.
The first Car object (“Beetle”) becomes unreachable after its sole reference, beetle, is reassigned. Note that object could be reachable even after one of its references is reassigned. For instance, in the following code, the Car object created on line 4 is accessible even after line 6 is executed.
4. Car beetle = new Car(“Beetle”);
5. Car funcar = beetle;
6. beetle = new Car();
After execution of line 5, the Car object created in first line has two references, beetle and funcar. At line 6, one of the references beetle is reassigned, but there is still one reference, funcar which points this Car object. Therefore, it is reachable and hence is not eligible for garbage collection yet.
In the examples we have discussed so far, we have seen the object references, which are stored on the stack because they were local variables. However, an object itself can store an object reference as one of its members. Since objects are created on heap, the member object reference is not stored on the stack. The object referenced by member reference is reachable only when the object of the member variable itself is reachable. In the next section, we will see the example of such objects.


Chapter Summary

Java has automatic memory management. Garbage collector is part of JVM responsible for recycling the allocated memory to java objects.
Garbage Collection cannot be forced explicitly. JVM may do garbage collection if it is running short of memory.
The call System.gc() or ( new Runtime().gc() ) does not force the garbage collection but only suggests that the JVM may make an effort to do garbage collection.
Garbage Collection is hardwired in Java runtime system. Java runtime system keeps the track of memory allocated. Therefore, it is able to determine if memory is still usable by any live thread. If not, then garbage collector will eventually release the memory back to the heap.
Garbage Collection usually adopts algorithm, which gives fair balance between responsiveness (how quickly garbage-collection completes) and speed of memory recovery. Responsiveness is especially important in real time systems whereas quick memory-recovery is important for memory-intensive operations.
How an object becomes eligible for Garbage Collection
q An object is eligible for garbage collection when no object refers to it.
q An object also becomes eligible when you explicitly set all its references to null.
q An object also becomes eligible when you explicitly reassign all its references to point to another object or null.
q Object created in method and referenced by method variables are eligible for garbage collection when the method returns unless its reference is returned by method.
q You can not …
Force garbage collection
Know exactly when it will happen
Know for sure which algorithms are used for garbage collection
q You can ….
Tell when the object becomes eligible for garbage collection
Explicitly make an object eligible for garbage collection
Request garbage collection
q The finalize() method
It is called only once by the garbage collector before deleting unreachable object.
As garbage collector makes no guarantees, the finalize()method may never run
You can make object ineligible for garbage collection in the finalize() method.




No comments:

Post a Comment