有没有办法避免Tomcat中的解除部署内存泄漏?
这个问题适用于任何曾经测试过Tomcat管理器中的“Find leaks”按钮并获得如下结果的人:
以下Web应用程序已停止(重新加载,未部署),但它们之前运行的类仍然加载到内存中,从而导致内存泄漏(使用分析器进行确认):
/漏的应用程序名称
我认为这与您经常通过重新部署获得的“Perm Gen space”错误有关。
所以当我部署时,我在jconsole中看到的是我的加载类从大约2k到5k。 那么你会认为一个解雇会让他们回落到2K,但他们仍然在5K。
我也尝试使用以下JVM选项:
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
我看到使用Perm Gen空间的次数非常少,但并不是我所期望的,而且加载的班级数量没有下降。
那么有没有办法配置Tomcat或者设计你的应用程序来更好地卸载? 或者我们坚持在一些重要的调试会话后重新启动服务器?
Tomcat版本输出:
服务器版本:Apache Tomcat / 6.0.29
服务器构建:2010年7月19日1458
服务器号码:6.0.0.29
操作系统名称:Windows 7
操作系统版本:6.1
架构:x86
JVM版本:1.6.0_18-b07
JVM供应商:Sun Microsystems Inc.
更新:
感谢celias的回答,我决定做更多的挖掘工作,并且我认为我确定了罪魁祸首要归功于CXF,Spring和JAXB。
在我学会了如何剖析Java应用程序之后,我将探查器指向了Tomcat,并采取了一些堆转储和快照来查看内存中对象和类的样子。 我发现我的CXF / JAXB(wsdl2java)生成的类中使用的XML模式中的一些枚举在取消部署后依然存在。 根据我的堆转储,它看起来像对象绑定到一个地图。 免责声明:我承认我仍然有点绿色,分析和跟踪一个对象的调用树在Java中可能具有挑战性。
另外我应该提到,我甚至没有调用服务,只是部署,然后取消部署。 对象本身似乎是通过部署时从Spring发起的反射来加载的。 我相信我遵循了在春季设立CXF服务的惯例。 所以我不能100%确定这是Spring / CXF,JAXB还是反射的错误。
作为一个附注:有问题的应用程序是使用Spring / CXF的Web服务,而XML恰好是一个相当复杂的模式(NIEM的扩展)。
如果你想确保不造成泄漏,你必须做到以下几点:
这里也是一篇关于ThreadLocal和MemoryLeaks的好文章 - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/
Tomcat 7应该在这方面带来改进。 请参阅Apache Tomcat 7的特性,标题为“不要泄漏!
他们相信他们现在可以处理由Web应用程序引起的大量内存泄漏。 不幸的是,它仍处于测试阶段。
除此之外,我可以说我已经取得了相同的经历并且没有找到解决方案。 之后部署通常需要重新启动Tomcat。 我不知道谁是罪魁祸首:我的Web应用程序,Tomcat,Hibernate,Tapestry或其中几个。
链接地址: http://www.djcxy.com/p/19829.html上一篇: Is there a way to avoid undeployment memory leaks in Tomcat?