Recently, I was invited to one company for an interview as a Java programmer. At the interview we were talking about the work of the finalize method. I had only a superficial understanding of the work of this method and could not give a decent description of the interviewers. Therefore, after the interview, I had to work on the bugs and figure it out.
My knowledge was limited to the fact that the finalize method is called at the moment when the garbage collector starts to dispose of the object. And I did not quite understand what it is for. I thought it was something like a destructor, in which you can release certain resources after they are no longer needed, and even the resources that are stored in other objects, which is not true.
So, the first thing that was needed to understand was the purpose.
This method is intended to automatically release the system resources occupied by the object on which this method will be called. It seems convenient not to remember all the time, for example, that we have to close the connection to some resource when it is no longer required.
')
Do not rely on finalize data cleaning. First, there is no guarantee that it will be called, since somewhere there may be a link to the object. Secondly, there is no guarantee at what time the method will be called. This is due to the fact that after the object becomes available for assembly and, if the finalize method is overridden in it, it is not called immediately, but placed in a queue, which is processed by a specially created thread. It should be noted that only those objects that have the finalize method redefined are queued for finalization.
There is a possibility that this method will not be called at all. This can happen at the moment when the object becomes available for the garbage collector and the program completes its work.
An interesting feature of the method is that it can again make an object accessible by assigning this to some variable, although it is not recommended to do so, because when restoring an object, finalize again will not be called
Another rare moment can happen. We have class A, in which the finalize method is implemented. We create a class B extends A in which we forget about finalize. Class B objects contain a lot of data. When objects of class B become unnecessary, they will be queued for finalization and will take up some time for the memory, instead of bypassing this queue and immediately being disposed of.
Another disadvantage is that you have to remember about calling the finalize-method of a super-class, if we override it. The developer will not cause - no one will.
Exceptions thrown in the finalize method are not handled by the finalizer thread, i.e. This box will probably not be tracked.
There is one way to make sure that finalize methods were run for objects that are available for assembly: call
System.runFinalization () or Runtime.getRuntime (). RunFinalization (). The exit from the method is carried out only when all available methods of objects for finalization are executed.
For myself, I concluded that using this method without special need is not worth it, and cases of this special need have not yet been met in my two-and-a-half-year practice.
It is better to write methods of the type close in java.io instead of finalize and call them in the finally block. The disadvantage is that the development should remember that the resource should be closed after use. Java SE 7 came to the rescue here with its
try-with-resourcesBut after all this method for something is. Where and how can it be used? Are there examples of use?
Finalize can be used as the last chance to close a resource, but never as the first or only attempt. Those. in addition to the fact that a client can call, for example, a close method on an object representing a resource. And maybe forget. Then you can try to help him. This is done, for example, in the FileInputStream.java class:
protected void finalize() throws IOException { if ((fd != null) && (fd != FileDescriptor.in)) { runningFinalize.set(Boolean.TRUE); try { close(); } finally { runningFinalize.set(Boolean.FALSE); } } }
This approach is often used in Java libraries.
Ps. Please do not take written for the truth. I wrote only how I understood the material read. I will gladly accept any additions, criticism and corrections.
References:
How to Handle Java Finalization's Memory-Retention IssuesJava Finalize method calljava.lang. Class object10 points on finalize method in Java - Tutorial ExampleHabrahabr. Finalize and Finalizer