What happened internally (JVM) when System.gc() or finalize() method called?
Is this really collect garbage or reduce performance ?
What happened internally (JVM) when System.gc() or finalize() method called?
Is this really collect garbage or reduce performance ?
Exactly what happens when you call System.gc() is JVM dependent. The JVM looks at this call as a suggestion that it might be a good time to run the garbage collector, so don't depend on it.
An object's finalize() method is run on an object by the garbage collector when the JVM determines that there are no more reachable references to that object. You shouldn't call it in your code. Keep in mind that finalize() is not called at the time when your program loses that final reference, but at a future time when the garbage collector is run, so don't depend on it happening at a specific point in time (or at all).
If you want to know garbage collection internals, you should read Hotspot Memory Management Whitepaper from Sun.
By invoking System.gc()
the garbage collector is run, as the name says. At this point, when the objects are really being removed, the finalize()
is called on these objects before they vanish.
The last question shouldn't have an "or
" in it. It is garbage collection and reduced performance.
Usually you shouldn't care about gc
at all because it does a really good job for you. There are usage scenarios where you want to get rid of a lot of objects at a certain point in time; Then it is feasible.
System.gc() cleans up memory, and uses finalize() to get rid of the individual objects.
Yes System.gc(); will trigger finalize() method if required. public class TestGarbageCollection {
public static void main(String[] args) {
while (true) {
TestClass s = new TestClass();
s.display();
System.gc();
}
}
}
public class TestClass {
public TestClass() {
System.out.println("constructor");
}
public void display() {
System.out.println("display");
}
@Override
public void finalize() {
System.out.println("destructor");
}
}
This will trigger finalize() method. whether you override finalize or not finalize method of local class or Object's finalize will be called.
finalize() is a means to execute final bit of code just before the object is ready for garbage collection ( when the object has no strong reference to it).
So when should it be used? Only in the present two cases:
Apart from the above two cases never use it. To understand why? we need to understand the functioning and lifecycle of an object.
Introduction: There is a separate daemon thread called as finalizer thread which is responsible for calling finalize() method . Finalization queue is the queu where objects which are ready to be called finalize() method are placed.
When an object is ready for garbage collection, then the garbage collector thread checks if this particular object has finalize() from table mentioned in (1).
2a) If it doesn’t then it is sent for garbage collection.
2b) It is has, then it is added to the finalization queue. And it removes the entry of the object from the table (1).
Finalizer thread keeps polling the queue. For every object in the queue, its finalize() method is called. After calling the finalize() cycle from (2) is again repeated. If this object still has no strong reference, then sent for GC. If it has then ALWAYS (2a) is called because the entry was deleted in (2b)
Basically finalize() method is only called once.
So what’s the issue with the above cycle?
From (1). Its take extra time in object creation. Memory allocation in Java is 5x to 10x faster than malloc/calloc etc. All the time gained is lost in the procedure of noting the object in the table etc. I once tried it. Create 100000 objects in a loop and measure the time taken for program to terminate in 2 cases: One with no finalize(), Second with finalize(). Found it to be 20% faster.
From (2b): Memory Leakage and Starvation. If the object in the queue has references to a lot of memory resources, then all those objects wont get freed unless this object is ready for GC.If all the objects are heavy weight objects, then there can be a shortage.
From (2b): Because finalize() is called only once, what if in teh finalize() you had a strong reference to “this” object. Next time the object’s finalie() is never called hence can leave the object in an inconsistent state.
If inside finalize() an exception is thrown, it is ignored.
You do not know when finalize() is called as you have no control over when GC is called. Sometimes it might happen that you are printing the value’s in finalize() but the output is never shown, because your program might have got terminated by the time finalize() is called.
Hence avoid using it. Instead create a method say dispose() which will close the necessory resources or for final log etc. the complete post on it. I hope this clears.