Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to clean up an Object in Java?

Tags:

java

We don't have any destructor in Java as we have in C++.

Q1. How should we clean up any Object in java.

Q2. Is there any alternative to a finally block.

Q3. Sometimes we have to call explicitely initialization/termination of a third party code from our class e.g.

public classs MyClass{
    public MyClass(){
        ThirdPartyInitialize();
    }

    protected void finalize(){
        ThirdPartyTerminate();
    }
}

Is this the correct way?

like image 643
pankajt Avatar asked Sep 04 '09 17:09

pankajt


People also ask

What are cleaners in Java?

Cleaner manages a set of object references and corresponding cleaning actions. Cleaning actions are registered to run after the cleaner is notified that the object has become phantom reachable. The cleaner uses PhantomReference and ReferenceQueue to be notified when the reachability changes.

How do you free an object in Java?

Java Delete an Object by Referencing It to null But after that, we want to delete myObject so that it cannot be used further. To do this, we initialize myObject once again but with null. Once the myObject is null , we cannot use it to call any of its methods or variables, and it will throw an exception if we do so.

Which method is used to clean up the memory space occupied by an object in Java?

You can use methods like free() in C, and delete() in C++ to perform Garbage Collection. In Java, garbage collection happens automatically during the lifetime of a program. This eliminates the need to de-allocate memory and therefore avoids memory leaks.

How do you remove an object from an object in Java?

The remove(Object obj) method of List interface in Java is used to remove the first occurrence of the specified element obj from this List if it is present in the List. Parameters: It accepts a single parameter obj of List type which represents the element to be removed from the given List.


6 Answers

You generally cannot "clean up" Java objects yourself. The garbage collector decides when to clean objects up. You can indicate when you are done with an object reference by setting it to null, but generally just letting it go out of scope is good enough. Either way, you still have no control over when it gets garbage collected.

The finally block is intended for performing actions whether an exception is thrown from a try block or not, and is the best place to perform clean up. Generally you only would clean up non-object resources like open streams.

finalize() is not guaranteed to be called because the garbage collector is not guaranteed to be called before your program exits. It is not really like a C++ destructor because C++ destructors are always called and you can rely on them being called. You cannot rely on finalize() being called.

So 1) use finally blocks to release non-object resources 2) let the garbage collector clean up object-resources 3) you can hint to the garbage collector that you are done with an object by setting it to null if it is used in a long-running method.

like image 55
SingleShot Avatar answered Oct 14 '22 09:10

SingleShot


You could also add a shutdown hook to your program, if your program is shutting down too:

//add shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        ThirdPartyTerminate();
    }
});
like image 29
dave4351 Avatar answered Oct 14 '22 07:10

dave4351


Two syntax sugar options:

1) There is a @Cleanup annotation in Lombok that mostly resembles C++ destructors (more):

@Cleanup
ResourceClass resource = new ResourceClass();

2) There is also try-with-resources statement. For example:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
}
like image 31
Alexey Avatar answered Oct 14 '22 07:10

Alexey


The best way to clean up after objects is to just drop the object.

Finally blocks can be abstracted using the Execute Around idiom.

Finalisers should be avoided. They probably wont get called immediately. The clean up should happen anyway. They are relatively slow. You might want to add one as a safety-net if you are writing a low-level resource wrapper (for, say, a file handle) if performance is not critical.

like image 40
Tom Hawtin - tackline Avatar answered Oct 14 '22 07:10

Tom Hawtin - tackline


You can clean up objects by removing references to it, when you no longer need it. You dont have to do it explicitly. An explicit cleanup would require setting the reference to null, thereby providing a hint to the garbage collector that the object can be collected. This hint works because of internal reference counts for each object, that are maintained internally. For instance


C a = new C(); //create an object of class C and assign it to 'a'
a = new C(); //create another object of class C and assign it to 'a'. The older object is no longer referred to. It is now eligible for GC.

There are better alternatives to finalize() depending on how much finalize() is helping your situation.

Often, the best practice is to provide a method like close() or disposeResources() in the API which will allow the caller to help the API clean up itself. For instance, the java.sql.Connection class does this. This is better than the finalize() method, since the JVM will call the finalize() method. Often the finalize() method will be run by a low priority thread in the JVM, leading to certain strange errors.

In the case of the Connection class, waiting for the JVM to perform finalization does prove costly in a lot of applications, since a database can accept only so many connections at a time. Therefore, most programmers will call close() explicitly on a Connection object.

In your case, it should translate into something similar (and in this context, the finally block is guaranteed to run always)


try
{
 ThirdPartyInitialize();
 // use third party component in this try block
}
finally
{
 ThirdPartyTerminate();
}

This is similar to the how the Connection class is also used in most situations.

like image 25
Vineet Reynolds Avatar answered Oct 14 '22 08:10

Vineet Reynolds


You can use java.lang.ref.Cleaner in Java 9,

like image 24
Glavo Avatar answered Oct 14 '22 07:10

Glavo