Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is finalize not being called?

I have couple of questions regarding garbage collector in java.

Q1.As far as I understand, finalize() gets called when object is out of scope and JVM is about to collect garbage. I thought finalize() method is called automatically by garbage collector, but it does not seems to work in this case. What is the explanation? Why is the need for me to explicitly call finalize() method?

public class MultipleConstruct {
    int x,y;    
    public MultipleConstruct(int x)
    {
        this.x= x;
        y=5;        
        System.out.println("ONE");
    }

    @Override
    protected void finalize() throws Throwable {
        // TODO Auto-generated method stub
        super.finalize();
        System.out.println("FINALIZED");
    }
    public static void main(String[] args) throws Throwable {
        MultipleConstruct construct = new MultipleConstruct(3);
    }
}

Q2. Also, when is garbage collector invoked? I understand gc is a daemon thread and invoked by JVM depending on heap size remaining. Does that mean, JVM waits for the program to use threshold limit of resources and then notify the gc to sweep garbage objects.

EDIT: How does gc resolved circular references?

like image 646
prap19 Avatar asked Oct 16 '11 20:10

prap19


People also ask

Is finalize guaranteed to be called?

finalize method is not guaranteed. This method is called when the object becomes eligible for GC. There are many situations where the objects may not be garbage collected.

Why is finalize deprecated?

Deprecated. The finalization mechanism is inherently problematic. Finalization can lead to performance issues, deadlocks, and hangs.

Can we call Finalize method?

Since the Object class contains the finalize method hence finalize method is available for every java class since Object is the superclass of all java classes. Since it is available for every java class, Garbage Collector can call the finalize() method on any java object.

WHO calls Finalize method?

finalize() is called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup.


2 Answers

There is a lot to finalize() method which is frankly a lot to write, but in short:

An object is in the finalized state if it is still unreachable after its finalize method, if any, has been run. A finalized object is awaiting deallocation. Note that the VM implementation controls when the finalizer is run. You are almost always better off doing your own cleanup instead of relying on a finalizer. Using a finalizer can also leave behind critical resources that won't be recovered for an indeterminate amount of time.

In your case the reason it does not print is that you do not know when the finalizer thread will call the finalize() method. What is happening is that the program is terminating before anything can get printed. To check it: edit the code inside main code by( NOTE: this does not guarrantee nor should you should ever rely on it but still it does prints some time)

for(int i =0;i<1000000;i++)
    {
        MultipleConstruct construct = new MultipleConstruct(3);
        construct = null;
    }

There are a lot of disadvantages of using a finalize() right from taking more time in object construction to possibility of memory leakage and memory starvation. If you strongly refer to the same object inside the finalize() then it is never called the second time and thus can leave system in undesired state etc etc etc... The only place where you should use finalize() is as a safety net to dispose any resources like InputStream uses it to close (which again there is no guarrantee that it will will br run when your program is still alive). Another place to use it is while using natives where garbage collector has no control.

For more info visit:

http://jatinpuri.com/?p=106

like image 91
Jatin Avatar answered Sep 26 '22 06:09

Jatin


q1) finalize method is called when the object is being garbage collected, thus, if no GC is being performed, your finalizer may not be called. You need to call super simply to preserve the behavior provided by Object implementation.

q2) the exact moment in which GC is performed depends on a lot of factors like: which JVM you are using, tuning parameters, amount of free heap, etc. So it does not only rely on a used heap threshold. You can also ask for a GC to be performed through System.gc() but you have no guarantee about if and when it will be actually executed. You can find some details on how to configure GC in http://java.sun.com/performance/reference/whitepapers/tuning.html

like image 26
fpacifici Avatar answered Sep 22 '22 06:09

fpacifici