is memory leak? why java.lang.ref.Finalizer eat so much memory
Asked Answered
B

3

73

I ran a heap dump on my program. When I opened it in the memory analyzer tool, I found that the java.lang.ref.Finalizer for org.logicalcobwebs.proxool.ProxyStatement was taking up a lot of memory. Why is this so?

screenshot

Beetroot answered 2/12, 2011 at 10:40 Comment(3)
The "images" link goes to what appears to be your twitter profile.Sylas
@R.MartinhoFernandes It goes through to an image he has hosted with twitter, I think.Cobia
Note that as of Java 18, finalize is marked as deprecated for future removal; see JEP 421 and bugs.openjdk.org/browse/JDK-8274609. Either way, one approach to solving this problem is to go through your codebase and replace all uses of finalizers with try wth resources or cleaners. (And "encourage" the maintainers of all of your dependencies to do the same thing!)Sphincter
S
76

Some classes implement the Object.finalize() method. Objects which override this method need to called by a background thread call finalizer, and they can't be cleaned up until this happens. If these tasks are short and you don't discard many of these it all works well. However if you are creating lots of these objects and/or their finalizers take a long time, the queue of objects to be finalized builds up. It is possible for this queue to use up all the memory.

The solution is

  • don't use finalize()d objects if you can (if you are writing the class for the object)
  • make finalize very short (if you have to use it)
  • don't discard such objects every time (try to re-use them)

The last option is likely to be best for you as you are using an existing library.

Sclar answered 2/12, 2011 at 10:47 Comment(6)
Option #4 - avoid using libraries that (over-)use finalizers.Sphincter
A variation of option #1 ;)Sclar
maybe the problem is the cause of Finalizer thread. one class override the finalize methond ,cause the Finalizer thread dead lockBeetroot
If you have an object which dead locks in the finalise, there is nothing you can do except fix the bug or use another library. Its not something you can fix externally.Sclar
@Peter Lawrey you are right ,Because Object.finalise() cause memroy leakBeetroot
I noticed this happening to me on Android when using lots of regexp Pattern/Matcher instances (which are released right after being used), when I run out of memory, I see 50% of my heap being occupied by these FinalizerReferences that point to either my Pattern or Matcher instances (and no other references exists to those objects in the heap map).Resemblance
S
11

From what I can make out, Proxool is a connection pool for JDBC connections. This suggests to me that the problem is that your application is misusing the connection pool. Instead of calling close on the statement objects, your code is probably dropping them and/or their parent connections. The Proxool is relying on finalizers to close the underlying driver-implemented objects ... but this requires those Finalizer instances. It could also mean that you are causing the connection to open / close (real) database connections more frequently than is necessary, and that would be bad for performance.

So I suggest that you check your code for leaked ResultSet, Statement and/or Connection objects, and make sure that you close them in finally blocks.


Looking at the memory dump, I expect you are concerned where the 898,527,228 bytes are going. The vast majority are retained by the Finalizer object whose id is 2aab07855e38. If you still have the dump file, take a look at what that Finalizer is referring to. It looks more problematic than the Proxool objects.

Sphincter answered 2/12, 2011 at 11:5 Comment(0)
M
0

It may be late, But I had a similar issue and figured out that we need to tune up the garbage collectors, Can't keep serial and parallel GC, and G1 GC was also not working properly. But when using concurrentMarkSweep GC we were able to stop building this queue too large.

Massie answered 18/7, 2022 at 6:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.