Is there a destructor for Java?
Is there a destructor for Java? I don't seem to be able to find any documentation on this. If there isn't, how can I achieve the same effect?
To make my question more specific, I am writing an application that deals with data, and the specification say that there should be a 'reset' button that brings the application back to its original just launched state. However, all data have to be 'live' unless application is closed or reset button is pressed.
Being usually a C/C++ programmer, I thought this would be trivial to implement. (And hence I planned to implement it last.) I structured my program such that all the 'reset-able' objects would be in a same class so that I can just destroy all 'live' objects when reset button is pressed.
I was thinking, if all I did was just to dereference the data and wait for the garbage collector to collect them, wouldn't there be a memory leak if my user repeatedly entered data and pressed the reset button? I was also thinking, since Java is quite mature as a language, there should be a way to prevent this from happening or gracefully tackle this.
Because Java is a garbage collected language you cannot predict when (or even if) an object will be destroyed. Hence there is no direct equivalent of a destructor.
There is an inherited method called finalize
, but this is called entirely at the discretion of the garbage collector. So for classes that need to explicitly tidy up, the convention is to define a close method and use finalize only for sanity checking (ie if close has not been called do it now and log an error).
There was a question that spawned in-depth discussion of finalize recently, so that should provide more depth if required...
Nope, no destructors here. The reason is that all Java objects are heap allocated and garbage collected. Without explicit deallocation (ie C++'s delete operator) there is no sensible way to implement real destructors.
Java does support finalizers, but they are meant to be used only as a safeguard for objects holding a handle to native resources like sockets, file handles, window handles, etc. When the garbage collector collects an object without a finalizer it simply marks the memory region as free and that's it. When the object has a finalizer, it's first copied into a temporary location (remember, we're garbage collecting here), then it's enqueued into a waiting-to-be-finalized queue and then a Finalizer thread polls the queue with very low priority and runs the finalizer.
When the application exits, the JVM stops without waiting for the pending objects to be finalized, so there practically no guarantees that your finalizers will ever run.
If you use Java 7, have a look at the try-with-resources statement. For example:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
System.out.println(br.readLine());
} catch (Exception e) {
...
} finally {
...
}
Here the resource that is no longer needed is freed in the BufferedReader.close()
method. You can create your own class that implements AutoCloseable
and use it in a similar fashion.
This statement is more limited than finalize
in terms of code structuring, but at the same time it makes the code simpler to understand and maintain. Also, there is no guarantee that a finalize
method is called at all during the livetime of the application.
上一篇: 内存泄漏是否正常?
下一篇: 有没有Java的析构函数?