Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do you not explicitly call finalize() or start the garbage collector?

After reading this question, I was reminded of when I was taught Java and told never to call finalize() or run the garbage collector because "it's a big black box that you never need to worry about". Can someone boil the reasoning for this down to a few sentences? I'm sure I could read a technical report from Sun on this matter, but I think a nice, short, simple answer would satisfy my curiosity.

like image 758
Thomas Owens Avatar asked Aug 26 '08 19:08

Thomas Owens


People also ask

Why do we need a finalize () method when garbage collection is there?

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.

Why finalize () method should be avoided?

“This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.” So, in one way we can not guarantee the execution and in another way we the system in danger.

Can we call finalize method explicitly?

6) You can call finalize() method explicitly on an object before it is abandoned. When you call, only operations kept in finalize() method are performed on an object. Object will not be destroyed from the memory. 7) finalize() method on an abandoned object is called only once by the garbage collector thread.

Why is finalize not called?

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.


1 Answers

The short answer: Java garbage collection is a very finely tuned tool. System.gc() is a sledge-hammer.

Java's heap is divided into different generations, each of which is collected using a different strategy. If you attach a profiler to a healthy app, you'll see that it very rarely has to run the most expensive kinds of collections because most objects are caught by the faster copying collector in the young generation.

Calling System.gc() directly, while technically not guaranteed to do anything, in practice will trigger an expensive, stop-the-world full heap collection. This is almost always the wrong thing to do. You think you're saving resources, but you're actually wasting them for no good reason, forcing Java to recheck all your live objects “just in case”.

If you are having problems with GC pauses during critical moments, you're better off configuring the JVM to use the concurrent mark/sweep collector, which was designed specifically to minimise time spent paused, than trying to take a sledgehammer to the problem and just breaking it further.

The Sun document you were thinking of is here: Java SE 6 HotSpot™ Virtual Machine Garbage Collection Tuning

(Another thing you might not know: implementing a finalize() method on your object makes garbage collection slower. Firstly, it will take two GC runs to collect the object: one to run finalize() and the next to ensure that the object wasn't resurrected during finalization. Secondly, objects with finalize() methods have to be treated as special cases by the GC because they have to be collected individually, they can't just be thrown away in bulk.)

like image 99
Charles Miller Avatar answered Sep 27 '22 03:09

Charles Miller