Thursday, May 29, 2008

Garbage Collection

14. Will finalize method of all objects eventually be called?

A: The answer is yes, with an exception of JVM being killed abruptly for internal or external reasons.

If the your application is terminated normally, the finalize method of all objects eventually will be called. The simlest way to prove it would be writing a very small application with a few objects instantialized. All objects in your application have a finalize method with a println("XXX object finalize method is called now."); in it. Run it and see the result. This is because JVM will take care of it before normal exit. All objects are eligible for GC and will be GCed before JVM terminates. Of course, we are not considering the special case that JVM might have a bug. :)

However, what is the exception?
  • JVM is killed internally, by

    1. System.exit(1);

    2. Uncaught Exception being thrown at the top level.

    3. You may add more...

  • JVM is killed externally, by

    1. User use ctrl C or other system commands to kill it on windows, unix, or ...

    2. System power off.

    3. You may add more...

15. Any class that includes a finalize method should invoke its superclass' finalize method, why?

A:

The point is that finalize methods are not automatically "chained" - if you subclass a class that has an important finalize, your finalize method should call it. Obviously if you don't know what the superclass finalize method does, you should call it anyway, just to be safe.

By contrast, When you create an object with the new keyword, the superclass constructor(s) are called first. This is automatically "chained".

16. When an object becomes eligible for garbage collection?

A:

The object is no longer referenced or referenced only by objects, which are eligible for GC.An object becomes eligible for garbage collection when there is no way for any active thread to reach that object through a reference or chain of references. (An equivalent answer by Jim Yingst)Set all references to an object to null is sufficient for an object eligible to GC, but not necessary.

Here are two simple examples with proper comments:

public class Test1{
public static void main(String[] args) {
Object a = new Object();
Object b = a;
a = null;
// the Object is still referred by b.
// which is not eligible for garbage collection.

// an infinite loop here
int i = 0;
while (true){
i = i++;
}
//Using ctrl C to kill it, sorry!
}
}

public class Test2{
public static void main(String[] args) {
Object[] ary = new Object[5];
for (int i=0; i<5; i++) {
ary[i] = new Object();
}

// do something here

ary = null;
//Now all objects in the array are eligible for GC
// even none of their references are null.
}
}

17. Can circular reference prevent objects from be garbage collected?

A: No! Prove by counter example:

class Test1 {
public static void main(String arg[]) throws Exception{

MyObj a = new MyObj("a");
MyObj b = new MyObj("b");

//circular reference here
a.o = b;
b.o = a;

a = null;
b = null;
// a and b are both eligible for GC now

MyObj c = new MyObj("c");
c.o = new MyObj("d"); //when c dies, d dies too.
c = null;

// an infinite loop here
// use ^c to kill it

MyObj[] objAry = new MyObj[1024];
int i = 0;
while (true){
// suggest JVM to GC
System.gc();

// use more memory here
i %= 1024;
objAry[i] = new MyObj("X" + i);

i++;
Thread.sleep(5); // Give CPU some breath time
}
}
}

class MyObj {
MyObj o;
String s;
long[] ary = new long[4096]; // make MyObj big

MyObj(String s) {
this.s = s;
}

protected void finalize() throws Throwable {
// Make GC visible
System.out.println(s + ": I am dying");
super.finalize();
}
}

18. How many objects are eligible for GC in the following code after d = null?

public class Test{
public static void main(String[] args) {
Object a = new Object(); // the object original referenced by object reference a
Object b = new Object();
Object c = new Object();
Object d = new Object();

d=c=b=a;
d=null;
}
}

A:

Just remember that operator = is right associate, and then you should be able to figure out the answer by yourself. The equivalent statement is d=(c=(b=a)); The example in here following can be used to get the answer you need too, minor change required.

Answer: Three.
1) After b=a, the object original referenced by b is eligible for GC.
2) After c=(b=a), the object original referenced by c is eligible for GC.
3) After d=(c=(b=a)), the object original referenced by d is eligible for GC.
4) After d=null, nothing new is eligible for GC.
5) The object original referenced by a is not eligible for GC, since it is still referred by references a, b, c. 6) Make sure you understand the differences between physical object and object reference (pointer to object).

19. In garbage collection mechanism, what is vendor/platform dependent? What is not?

A:

How GC implemented is vender and platform dependent. Which means:

It is vender and platform dependent that when and in what order the eligible for GC objects will be GCed.

However, which objects are eligible for GC is independent of implementations. Different vendor may use different algorithms. What algorithm used to find the objects, which are eligible for GC does not matter. What really matters is that they use the same principle.

The object is no longer referenced or referenced only by objects, which are eligible for GC.

Unless they have a bug...

20.Can an object be garbage collected, but a field of it is still alive?

A: Sure, as long as it is still referred by something.

Actually, this is used by many design patterns, e.g. Factory Method pattern. See the following example, read the comments carefully!

// UseSimple.java
class Simple {
void writeSomething(String msg) {
System.out.println("Simple.writeSomething: " + msg);
}

protected void finalize()throws Throwable{
System.out.println("Finalize:Simple");
super.finalize();
}
}

class CombineSimple{
private Simple simFld;

Simple getSimpleField() {
if( simFld == null ) {
simFld = new Simple();
}
return simFld;
}
protected void finalize()throws Throwable{
System.out.println("Finalize:CombineSimple");
super.finalize();
}
}

public class UseSimple {
public static void main(String[] args) {
CombineSimple csObj = new CombineSimple();
Simple simObj = csObj.getSimpleField();

csObj = null;

// Since GC cannot be forced
// we make sure csObj is GCed.
System.gc();
for (int i=0; i<3; i++){
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
System.gc();
}

// The simFld field of csObj will be still alive
// since it is still referred by simObj
simObj.writeSomething("I am still alive!");
}
}

21. What is mark and sweep garbage collection algorithm, is there other algorithms?

A:

The question is out of the scope of SCJP, however, it will help you in job-hunting process. Here is a beautiful applet, which will give you the basics, and have fun: Heap of Fish, A Simulation of a Garbage-Collected Heap

1 comment:

adawaechter said...

Casino Finder - Harrah's Philadelphia - MJH
Use 당진 출장안마 our casino Finder to quickly see all 김제 출장샵 Harrah's Philadelphia Casinos 순천 출장마사지 and Racetracks. 777 Harrah's Blvd 익산 출장마사지 Harrah's Philadelphia, PA 영천 출장마사지 19013-5343.