即使没有gc root,WebappClassLoader内存也会泄漏

gga*_*iao 6 java tomcat memory-leaks yourkit classloader

这是HEAD DUMP(2013年10月29日更新)

我正在使用webapp工作:

  • Tomcat 7.0.24
  • Java 6
  • 春天3(与aop - cglib)
  • Log4j上的SLF4J
  • Oracle Coherence

经过大量的工作,我设法删除了对类加载器的所有强引用,现在它是垃圾收集器的候选者.那么,内存泄漏解决了吗?当然不是!因为在几次热部署之后,由于PermGen空间而出现了OOME.

感谢Yourkit,我能够检查是否WebappClassLoaderPending Finalization,这意味着它正在终结队列中等待(实际上,不是WebappClassLoader自己而是他的指示对象之一).检查内存快照我发现了几个Finalizer对Oracle Coherence类的引用...... 在此输入图像描述

这似乎是"okey":Coherence对象正在等待垃圾收集,这要归功于删除所有强引用(删除所有一致性线程,删除java安全提供程序等)所做的所有艰苦工作.我想这里没什么可做的.

所以,我正在考虑一些finalize破坏某些东西然后不允许清空终结器队列的执行.但奇怪的是,使用JMX或jmap -finalizerinfo终结器队列似乎是空的!这一切都很混乱所以我一直在其他地方搜索......

你认为这是可以做的吗?我读过一些关于CGLIB增强finalize方法的内容.如果我有权访问,Enhancer我可以创建一个回调过滤器,如下所述,但我不知道如何使用Spring AOP来管理它.

好吧,在其他地方搜索,我发现了几个弱引用java.lang.reflect.Proxy.这些是jdk动态代理吗?或者它们与Introspection内存泄漏有关?弱参考?

在此输入图像描述

信息:我正在使用Spring的上下文监听器来刷新instrospector的缓存(java.beans.Introspector.flushCaches()).我还能做些什么呢?

让我们继续.

然后,我们还有其他几个弱引用java.io.ObjectStreamClass$Caches.我的很多业务对象都有这些弱引用.

在此输入图像描述 在此输入图像描述

也许我需要刷新这些缓存.但是怎么样?

然后我们有这些与之相关的弱参考com.sun.internal.ResourceManager,java.util.logging.Loggingjava.lang.reflect.Proxy

在此输入图像描述

我可以用这个弱引用做什么?我是否需要担心这个问题,或者问题出现在终结器队列中?任何线索都会有所帮助......真的:-D

Ah, another thing, I found a weak reference from a tomcat "main" thread that will not be renewed ever by tomcat. I know that my application can leave some thread local var in some tomcat threads, but tomcat 7 renew these threads to avoid class loader memory leaks. 在此输入图像描述

I think this is the oddest thing on my memory snapshot, but is a weak referece right? What I can do with this?

EDIT: Reading the java.lang.ref javadoc i found this:

An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.

So, can weak references retain objects in the heap when they implement a finalize method?

Meanwhile i found an answer to this, I manage to remove all the weak references to my classloader but two: ClassLoaderLogManager.classLoaderLoggers and the one related to the tomcat thread.

NOTE: Actually, I managed to remove the first one but this reference is set again by tomcat after/during undeployment.

EDIT: PLUMBR RESULTS

I've tried plumbr and no reports on the web console. Only this message on the standard output

Dumping heap to /opt/tomcat7/headdumps/java_pid9478.hprof ...
Heap dump file created [348373628 bytes in 3.984 secs]
#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (javaCalls.cpp:40), pid=9478, tid=1117813056
#  Error: guarantee(!thread->is_Compiler_thread(),"cannot make java calls from the compiler")
#
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode linux-amd64) [thread 1110444352 also had an error]
# An error report file with more information is saved as:
# [thread 1110444352 also had an error]
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#
******************************************************************************
*                                                                            *
* Plumbr has noticed that JVM has thrown an OutOfMemoryError: PermGen space. *
*                                                                            *
* You can increase PermGen size with -XX:MaxPermSize parameter.              *
* If you encountered this error after a redeploy, please read next article:  *
* http://plumbr.eu/blog/what-is-a-permgen-leak                               *
*                                                                            *
******************************************************************************
Run Code Online (Sandbox Code Playgroud)

Nik*_*kem 3

我认为 Yourkit 把你引向了错误的道路。

我已经使用 Eclipse Memory Analyzer 查看了您的堆转储。它表明,WebappClassLoader 由类 com.inovasoftware.iap.data.access.platform.datarepository.CoherenceDataRepository$$EnhancerByCGLIB$$180c0a4e 引用,该实例在某个线程局部变量中处于活动状态。一些谷歌搜索显示了这一点: https ://hibernate.atlassian.net/browse/HHH-2481

所以升级 Hibernate 版本可能会有所帮助。

垫截图