Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify the cause of a JNI global reference memory leak?

I'm using Tomcat and after stopping my web application there's still a reference to the classloader instance of my web application. With the consequence that a notable amount of memory (mostly related to static data) will not be freed. Sooner or later this results in an OutOfMemoryError.

I took a heap dump and I realized that its held by a JNI global reference which prevents that the classloader will be garbage collected.

My application does not use JNI. I am also not using the Apache Tomcat Native Library. I am using a Sun/Oracle JDK.
I'd like to track down the cause/origin of this global reference. (My guess is that the JVM internally references the classloader - but why/where?).

Question:

  • Which approaches/toolsets exists to achieve this?

UPDATE

It seems that bestsss is right and the JNI global references has been introduced by the jvm debug mode. This helped me out but it does not answer the question so I am still curious to get an answer to the question which might be helpful in the future.

like image 710
MRalwasser Avatar asked Jun 21 '11 10:06

MRalwasser


People also ask

How do you detect memory leaks?

The primary tools for detecting memory leaks are the C/C++ debugger and the C Run-time Library (CRT) debug heap functions. The #define statement maps a base version of the CRT heap functions to the corresponding debug version. If you leave out the #define statement, the memory leak dump will be less detailed.

What is JNI global references?

A JNI global reference is a reference from "native" code to a Java object managed by the Java garbage collector. Its purpose is to prevent collection of an object that is still in use by native code, but doesn't appear to have any live references in the Java code. A JFrame is a java. awt.

Which of the following action can cause memory leak?

Causes of Memory Leaks Using Unwanted Object Reference: These are the object references that are no longer needed. The garbage collector is failed to reclaim the memory because another object still refers to that unwanted object. Using Long-live Static Objects: Using static objects also leads to a memory leak.

What causes a memory leak?

DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.


2 Answers

Besides the obvious case: Threads, there is one more:

Are you using your application in debug mode?

The JVM does not hold references to any classloader besides the system one, but it doesn't concern you. The rest of JNI references are either Threads or just debug held objects (provided you don't use JNI and lock the objects down yourself).

JNI references are just roots, edit your answer and post what exactly objects are held by those references.

like image 189
bestsss Avatar answered Nov 01 '22 12:11

bestsss


The first thing i'd do is run with -Xcheck:jni on and see if it comes up with anything. I wouldn't expect it to; it doesn't sound there's anything weird happening with JNI, just incorrect use being made of it. However, it's good to make sure of that.

If you're on a Sun JVM, i think you can do -XX:TraceJNICalls to get an overwhelming listing of JNI calls as they happen. That should let you get an idea of what calls are being made, and from there work towards what is making them, and why this is causing a problem.

like image 28
Tom Anderson Avatar answered Nov 01 '22 12:11

Tom Anderson