A Constructor is
used whenever we want to create a Object. A finalizer is just an Opposite of
the Constructor. A constructor method
performs initialization for an object; a finalizer method performs finalization
for the object. Where do we use this finalizer? As we know Garbage Collector
take care of cleaning the memory used by Objects but Objects can hold many
types of resources like Sockets, Open File handlers etc. The garbage collector cannot free these resources for
you, so you need to help the GC by writing a finalizer method for objects that
needs to perform such tasks as closing files, terminating network connections,
deleting temporary files.
We know that Object
Class is the super class of all Classes. If we check the java.lang.Object we can see a method called “finalize”. The implementation of this
method is empty but when over ridden by the sub-class it gives you a lot of
power. Here is the sample Class by which we will see the danger in not using
the finalize method correctly. Here is a Sample code which will create the
finalize objects.
public class
finalizer {
@Override
protected void finalize() throws Throwable
{
while (true) {
Thread.yield();
}
}
public static void
main(String str[]) {
while (true) {
for (int i = 0; i < 100000; i++) {
finalizer force = new finalizer();
}
}
}
}
When we run the
code, we can see large number of Finalizer objects is being created in the
undermined loop. After running for some time we will face 2 cases.
1. The JVM crashes
generating use a Java heap dump
2. The JVM throws a
Out of Memory: GC OverHead limit exceeded.
In both the cases ,
the JVM crashes. So what exactly happens when a finalize method is used. JVM creates
a Watcher called for each and every one
of the Finalizable instances. This is called Finalizer. So Whenever
a Object with the finalizer method is created, a corresponding
java.lang.ref.Finalizer object is created. Now since these objects are being references
by the finalizer objects, these may take fill up the space in Eden causing
these objects to move from Eden to Old Space.
How does the GC
works with these Objects?
Now since Old space is filling up, a GC runs and only after this the GC
the JVM determines that these objects are being referenced only by finalizer
objects and nothing more. These objects are then marked for GC and ready for
cleaning. So the GC add all Finalizer
objects to a special queue at java.lang.ref.Finalizer.ReferenceQueue.
Only when all this process is completed, the application threads start to
work.
How does these
finalize objects are cleaned?
Once the objects are set for cleaning, a JVM thread is created called
“finalizer”. If we check the thread dump for the process we can see a thread
called
"Finalizer" daemon prio=10 tid=0x0962d000 nid=0x4836 runnable
[0xafaa8000]
java.lang.Thread.State: RUNNABLE
at
java.lang.Thread.yield(Native Method)
at
finalizer.finalize(finalizer.java:5)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native
Method)
at
java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at
java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at
java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
These is only one responsibility for this thread. This continuously
checks the java.lang.ref.Finalizer.ReferenceQueue Queue for new objects. So when ever a
new objects enters the Queue, the finalizer thread run the finalize method for
that object and removes the finalizer reference for that object. So in the next
GC cycle we will have this object and finalizer object both cleaned up.
Most cases the finalizer thread is fast enough
to clean the finalizer Queue by running the finalize method but in our case,
the finalizer is not fast enough to clean the objects that we create. One of the reasons is that the finalizer
thread is low priority thread causing to take less CPU time.
Hence the JVM crashes with Out of Memory
exceptions or by generating a Heap dump.
So It is always important to write a
Finalize() method to do a clean up but it is also important not to use high
number of finalize objects . One way is to deal with these is to increase the
priority of the "Finalizer" daemon thread - there is no API for this,
so you have to run through all the threads to find it by name, then increase
it's priority.
We can take control over the finalization by
removing the finalize() method and using our own explicit queue using your own
Reference objects in a very similar way that the Finalizer class processes the
objects and their finalize() methods
How does we find how many Finalizer objects exist?
We can use the jmap command as
tmp $ jmap
-finalizerinfo 18360
Attaching to
process ID 18360, please wait...
Number of objects pending for finalization: 4150245
…..
How much memory does the finalizer objects take?
We can use the jmap
command here too like
tmp $ jmap
-histo:live 14773
num
#instances #bytes class name
----------------------------------------------
1: 24855236 795367552
java.lang.ref.Finalizer
2: 24855230 198841840
finalizer
An article can be
found on how to find the finalizer leaks using Eclipse memory analyzer here.
What's up to all, it's in faact a goood ffor me
ReplyDeleteto pay a visit this web page, it contains valuable Information.
I was juist searching for this info for a while.
ReplyDeleteAfter 6 hours of continuous Googleing, finally I
got it in your web site. I wonder what's the lack of Google strategy that don't
rank this type of informative sites in top
of the list. Normally the top sitres are full of garbage.
Everyone loves what yoou guys tend to bee up too. This sort of coever work aand reporting!
ReplyDeleteKeep up the wonderful works guys I've incorporated you guys to my
blogroll.
Hi I am so delighted I found your site, I really found you by mistake, whike
ReplyDeleteI was looking on Digg for something else, Anyhow I am here now and would just
ike to say cheers for a marvelous post and a all round entertaining blog (I alsso love thhe theme/design), I don’t have time to ggo
through it all at the moment but I hae bookmarked
it and also added your RSS feeds, so when I have time I will
be back to read much more, Please do keep up the excellent work.
Hey very nice blog!
ReplyDeleteHi there mates, pleasant post and pleasant arguments commented here, I aam really
ReplyDeleteenjoying by these.