About Java Finalizers

Finalizers in Java Programming

Last week I shared three very short tips, all about deprecated functionality in Java. The essence of each tip was spot-on, but each tip deserves its own post. Let’s start with finalizers.

You’ve heard of Java finalizers. Finalizers are those magical methods that are supposed to free resources after objects have been marked as unreachable.

Purpose of Finalizers in Java

The garbage collector provides automatic memory management to Java applications. This means that the GC reclaims the memory used by an object when the object is no longer used.

When the garbage collector (GC) has determined that there are no more references to an object, it marks the object as unreachable. The GC then schedules the finalizers of unreachable objects to be called before it reclaims the memory being used by the objects.

However, if we use resources that are managed by the operating system, such as files or blocks of native memory, we need to close/return those resources to the OS. We can’t rely on the garbage collector to do this, because it only works with the JVM heap memory. If we forget to do that before the GC reclaims the object memory, then it becomes impossible to release the resource. The operating system will regard that resource as still in use, and it cannot reallocate the resource to any other program. The resource is then said to be leaked.

This is where the idea of finalization came in. Finalizers were introduced in the very first release of Java. Their purpose was to help prevent these resource leaks.

The finalizer method signature is protected void finalize() throws Throwable. It is inherited from the Object class. We can override the finalize() method to release any system resources that we might have opened (files, sockets, etc.) or to do any clean-up that we need.

Problems with Finalizers in Java

There are many problems with finalizers, not least being they are very hard to code correctly. They have security, reliability, and performance risks.

  • Unpredictable latency — There can be an unpredictable amount of time between an object becoming unreachable and the finalizer actually being called. The GC doesn’t even guarantee that a finalizer will ever be called.
  • Uncontrolled behaviour — Finalizer code is not constrained in any way and can do anything, even save a reference to the object being finalized. This will resurrect the object and make it reachable again.
  • Always enabled — Finalization is always enabled for every instance of the class, whether needed or not. Finalization cannot be cancelled, even if it is no longer necessary for a particular object.
  • Threading is unspecified — Finalizers get run by the JVM in an arbitrary order on unspecified threads. We can’t control either the ordering or the threading.
  • Performance issues — The GC has to do extra work when creating objects, and before and after finalizing them. There can be up to an order of magnitude slowdown for objects with finalizers.

Alternatives to Finalizers in Java

There are some recommended alternatives to using finalizers in your Java code:

  • Try-with-resources — The try-with-resources statement guarantees that the close() methods of the resources are called, whether exceptions were thrown or not.
  • Cleaners — Some resources live too long to let us use the try-with-resources mechanism. Java 9 introduced the Cleaner API to help release these resources. The Cleaner API allows a program to register a cleaning action for an object. This action is run some time after the object becomes unreachable.

Summary – Don’t use Finalizers in Java

The JEP 421: Deprecate Finalization for Removal has been closed and delivered in Java 18.

  • A command-line option has been added to selectively enable or disable finalization. It allows us to test our application to check if it relies on finalizers, and make the appropriate changes. Later versions of the JDK might even disable finalization by default.
  • All finalizers and finalization-related methods have been deprecated in the standard Java API.

So don’t be tempted to use finalizers! And if you have them, re-code them!

As always, please share your comments or any suggestions for blog posts.

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.