|help interpret results - finalize() making memory leak worse? [message #7836]
||Tue, 25 November 2008 23:02
Registered: July 2009
I'm trying to interpret the results from the memory analyzer (great tool, |
btw). The largest memory leak suspect is a group of
java.lang.ref.Finalizer objects. I've drilled down into it and identified
a class of ours that does have a finalize() method. It is part of our data
access layer. It wraps a ResultSet object, which contains a reference to
the PreparedStatement, which contains large Strings for the query that was
executed. The finalize method is used to make sure the Statement is
closed. Btw, I didn't write this, I've inherited support for it and found
many instances of bad code, which we're attempting to clean up.
From what I've read about this, some say that using a finalize() method
actually makes it take longer to garbage collect it; that it makes the Gc
take another round to actually clean it up, and using a finalize() method
creates a lot more overhead (like a bunch of Finalizer objects maybe? )
I guess my question is : What's the explanation for all the Finalizer
objects when my program ends? Is it just that they haven't yet had time to
be cleaned up? I've simply created a program that loads 1000 objects and
then quits and does the heap dump. I'm wondering if it were used in a
continually running server, that this stuff would be cleaned up eventually.
Should I try to find a way to remove the finalize() method?
|Re: help interpret results - finalize() making memory leak worse? [message #7856 is a reply to message #7836]
||Wed, 26 November 2008 20:54
| Andreas Buchen
Registered: July 2009
Finalizers are a broad field. Let me paste this paragraph which is hidden
deep in our help documentation:
Objects which implement the finalize method are included in the component
report, because those objects can have serious implications for the memory
of a Java Virtual Machine:
* Whenever an object with finalizer is created, a corresponding
java.lang.ref.Finalizer object is created. If the object is only reachable
via its finalizer, it is placed in the queue of the finalizer thread and
processed. Only then the next garbage collection will actually free the
memory. Therefore it takes at least two garbage collections until the
memory is freed.
* When using Sun's current virtual machine implementation, the finalizer
thread is a single thread processing the finalizer objects sequentially.
One blocking finalizer queue therefore can easily keep alive big chunks of
memory (all those other objects ready to be finalized).
* Depending on the actual algorithm, finalizer may require a
stop-the-world pause during garbage collections. This, of course, can have
serious implications for the responsiveness of the whole application.
* Last not least, the time of execution of the finalizer is up to the VM
and therefore unpredictable.
Huge memory kept alive by Finalizer objects can have multiple reasons.
Sometimes a finalizer is blocking the processing of the finalizer queue.
No objects are removed, the queue fills up, memory too, the OoM is a
natural conclusion then. Run "Java Basics" -> "Finalizer Overview". The
"Finalizer Thread Locals" tell you which objects are currently on the call
stack of the finalizer thread. This is the finalized object that might be
blocking - which does not be the type of objects, which mostly populate
the finalizer queue.
Hope this gives you some hints where to dig deeper.
Powered by FUDForum
. Page generated in 0.01768 seconds