java如何识别JNI全局引用内存泄漏的原因?
我正在使用Tomcat,在停止我的web应用程序后,仍然有对我的web应用程序的classloader实例的引用。
因此,大量内存(主要与静态数据有关)将无法释放。这迟早会导致OutOfMemoryError
我拿了一个heap dump
,我意识到它由一个JNI global reference持有,这阻止了类加载器将garbage collected
我的应用程序不使用JNI。我也没有使用ApacheTomcat本机库。我使用的是Sun/Oracle JDK
我想找出这个全球参考的原因/来源。
(我的猜测是JVM在内部引用类加载器——但是为什么/在哪里?)
问题:
- 有哪些方法/工具集可以实现这一点
更新
看来bestsss是对的,jvm调试模式引入了JNI全局引用。这帮了我的忙,但它并没有回答这个问题,所以我仍然很想得到一个对未来可能有用的答案
# 1 楼答案
你可以试试jstack
也许列出的stacktraces之一会向您显示全局引用的来源
# 2 楼答案
我要做的第一件事是在
-Xcheck:jni
打开的情况下运行,看看它是否有什么结果。我没想到会这样;听起来JNI并没有发生什么奇怪的事情,只是使用不当而已。然而,确保这一点很好如果您使用的是Sun JVM,我认为您可以通过
-XX:TraceJNICalls
获得大量JNI调用。这应该让你了解打电话的内容,并从中了解打电话的内容,以及这会导致问题的原因