Finalizer Performance Consequences for the JVM

According to this post , in .Net,

Finalizers are actually even worse than that. In addition, they are delayed (which is really a serious problem for many types of resources), they are also less efficient, since they can only perform a subset of the operations allowed in the destructor (for example, the finalizer cannot reliably use other objects, while the destructor can) and even when writing in this subset, finalizers are extremely difficult to write correctly. And the collection of finalized road objects: each final object and potentially huge graph of objects accessible from it, advances to the next GC generation, which makes it more expensive to collect at several large multiples.

Does this also apply to the JVM in general, and to HotSpot in particular?

+7
java finalizer
source share
4 answers

The following are some quotes from Effective Java 2nd Edition: Point 7: Avoid Finalizers:

Finalizers are unpredictable, often dangerous and not needed at all . Their use can cause erratic behavior, poor performance, and portability problems. Finalizers have few valid uses, [...] as a rule, you should avoid finalizers.

You really have to make sure that you really need finalizers; most of the time you are NOT.

C ++ programmers are cautioned not to think of finalizers as the Java counterpart of C ++ destructors. In C ++, destructors are a normal way to recover resources associated with an object, a necessary analogue for constructors. In Java, the garbage collector restores the storage associated with the object when it becomes inaccessible, without requiring much effort from the programmer. C ++ destructors are also used to recover other memoryless resources. In Java, a try-finally block is usually used for this purpose.

It is also important to consider the semantics of including finalizers:

JLS 12.6 Terminating Class Instances

The Java programming language does not indicate how soon finalizer [... nor] will be called, which thread will call the finalizer for any given object. [...] If an uncaught exception occurs during finalization, the exception is ignored and the completion of this object ends. (JLS 12.6.2) Finalizer statements are not ordered

In addition, the only mechanism for starting the finalizer on demand is violated. The following quotes from Effective Java 2nd Edition:

[...] The only methods that claim to guarantee completion are System.runFinalizersOnExit and its evil twin, Runtime.runFinalizersOnExit . These methods are deadly wrong and outdated.

Bloch went further to comment on the execution penalty (emphasis it):

Oh, and there is one more thing: there is a serious performance limitation when using finalizers . On my machine, the creation and destruction time of a simple object is about 5.6ns. Adding a finalizer increases the time to 2400 ns. In other words, it is about 430 times slower to create and destroy objects with finalizers.

With such little details on the benchmarking methodology, I don’t think that specific numbers mean a lot, but it confirms what has been widely documented: finalizers are very expensive.

The book explains rare scenarios in which the use of finalizers is valid. The absence of these quotes from this answer is intentional.

+3
source share

Here is an explicit expression from 2004:

Objects with finalizers (those that have a non-trivial finalize() method) have significant overhead compared to objects without finalizers and should be used sparingly. Completed objects both slow down and slow down collection. When allocating time, the JVM must register any terminated objects with the garbage collector, and (at least in the JVM HotSpot implementation), the final objects must follow a slower distribution route than most other objects. Similarly, completed objects are even slower to collect. It takes at least two garbage collection cycles (at best) before the final object can be recovered and the garbage collector needs to do extra work to call the finalizer. The result is more time to allocate and collect objects and more pressure on the garbage collector, since the memory used by inaccessible terminated objects lasts longer. Combine this with the fact that finalizers are not guaranteed to work in any predictable time frame or even in general, and you can see that there are relatively few situations for which finalization is the right tool to use.

+4
source share

Java has a very similar mechanism for finalizers. Here is a good article on finalizers: http://www.javaworld.com/javaworld/jw-06-1998/jw-06-techniques.html

A general rule of thumb in Java does not use them.

+1
source share

finalize () Called by the garbage collector on the object when garbage collection determines that there are no more links to the object. The subclass overrides the finalize method to recycle system resources or to perform another cleanup.

Do not use finalizers, mainly because they are unpredictable, and we do not know when it will be executed, "do not try to be smarter than JVM"

0
source share

All Articles