java.lang.finalize() method. To be used or not?

Aman Junaid
3 min readApr 18, 2021
Photo by Sabeer Darr on Unsplash

Use case

The scenario was like we had a class which was doing some database operation and in the end it was releasing the connection. But due to some challenges in some cases the connection was not being released.

The best was to handle this kind of scenario is to implement try-catch-final block or try with resource block which came in Java 7.

During the search for solution to this we came upon this method java.lang.finalize() method of Object class.

This method is called when the Java garbage collector determines that there is no more reference to an object. In this case the garbage collector destroys the object and releases memory so that it can be used in other operations.

This method will be called whenever an object is destroyed, so we thought if we implement this method to release connections and the resources acquired by the Object.

This is what we wanted, Right?? We want the database resources to be free once the object is free once the execution is done.

When we dig more into this, we found that its true that this method will be called when the object is destroyed but this is not in our hands when this Object will be destroyed and then this method will be called to release the acquired resources.

Here is the summary:

  1. Calling finalize() method is all dependent on the garbage collector of JVM. When the garbage collector destroys the object this method is called for the cleanup. Again this is dependent of hidden algorithm on the basis of which the Java JVM takes this decision.
  2. We cannot be dependent on the JVM for freeing the resource, it will definitely destroy the object, but we don’t know when.
  3. Garbage collection will take this decision on whether an object has to be destroyed or not on the basis of available environment, memory, etc.
  4. One of the important point is that, this method is deprecated in Java 9, so even if you can using this in your implementation you will have to move the implementation to other block as you will upgrade the java version.
  5. We also came across some blog posts which suggested that implementing the finalize method can result in the performance degrade as putting some logic in finalize block will result in slower garbage collection and in turn that will eventually impact the performance of the overall application and may even lead to system crash.
  6. Finalizers also have an impact on the program’s portability. Since the garbage collection algorithm is JVM implementation-dependent, a program may run very well on one system while behaving differently on another.
  7. If exception is not handled will in the finalize block and if a block throws an exception, the finalization process stops, leaving the object in a corrupted state without any notification. This will eventually result in system crash.

Solution:

  1. Try-catch-finally: Using this try-catch-finally block we can release the resource in the finally block to avoid any kind of resource leakage.
  2. Try with resource: This was introduced in Java 7, where you can declare and initialize the resource in the try block header and the resources will be released when the block is executed. Ex.
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql)) {
ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
}
} catch (SQLException e) {
e.printStackTrace();
}

3. AutoCloseable interface: This interface contains a close() method, when will called when ever the operation is complete.

public class CloseableResource implements AutoCloseable {
private BufferedReader reader;

public CloseableResource() {
InputStream input = this.getClass()
.getClassLoader()
.getResourceAsStream("file.txt");
reader = new BufferedReader(new InputStreamReader(input));
}

public String readFirstLine() throws IOException {
String firstLine = reader.readLine();
return firstLine;
}

@Override
public void close() {
try {
reader.close();
System.out.println("Closed BufferedReader in the close method");
} catch (IOException e) {
// handle exception
}
}
}

References: https://www.baeldung.com/java-finalize

--

--