有没有办法避免Tomcat中的部署内存泄漏? [英] Is there a way to avoid undeployment memory leaks in Tomcat?

查看:605
本文介绍了有没有办法避免Tomcat中的部署内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题适用于曾经测试过Tomcat管理器中查找泄漏按钮的人,并得到了一些结果:

This question is for anyone who's ever tested the "Find leaks" button in the Tomcat manager and got some results like this:


以下Web应用程序已停止(重新加载,取消部署),但之前运行的类仍然在内存中加载,从而导致内存泄漏(使用分析器确认):

/ leaky-app-name

The following web applications were stopped (reloaded, undeployed), but their classes from previous runs are still loaded in memory, thus causing a memory leak (use a profiler to confirm):
/leaky-app-name

我认为这与您经常通过频繁重新部署获得的Perm Gen space错误有关。

I'm assuming this has something to do with that "Perm Gen space" error you often get with frequent redeployments.

所以我在部署时在jconsole中看到的是我加载的类从大约2k到5k。然后你会认为取消部署应该将它们降低到2k但它们保持在5k。

So what I'm seeing in jconsole when I deploy is that my loaded classes goes from about 2k to 5k. Then you would think an undeployment should drop them back down to 2k but they remain at 5k.

我也尝试使用以下JVM选项:

I've also tried using the following JVM options:

-XX:+ CMSClassUnloadingEnabled -XX:+ UseConcMarkSweepGC -XX:+ CMSPermGenSweepingEnabled

我确实看到Perm Gen空间的使用量非常小,但不是我预期的,并且加载的类计数没有下降。

I did see VERY minor dips in the amount of Perm Gen space used but not what I expected and the loaded class counts did not drop.

那么有没有如何配置Tomcat或设计您的应用程序以便在取消部署时更好地卸载?或者我们是否在一些主要的调试会话后重新启动服务器?

So is there a way to configure Tomcat or design your app to unload better on an undeployment? Or are we stuck with restarting the server after some major debugging sessions?

Tomcat版本输出:

Tomcat version output:


服务器版本: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.

Server version: Apache Tomcat/6.0.29
Server built: July 19 2010 1458
Server number: 6.0.0.29
OS Name: Windows 7
OS Version: 6.1
Architecture: x86
JVM Version: 1.6.0_18-b07
JVM Vendor: Sun Microsystems Inc.

更新:

感谢celias的回答,我决定多做一些挖掘,我认为由于CXF,Spring和JAXB,我确定了应用程序的罪魁祸首。

Thanks to celias' answer I decided to do a little more digging and I think I determined the culprit to be in my application thanks to CXF, Spring and JAXB.

在我学习了如何分析Java应用程序之后,我将分析器指向Tomcat并获取了一些堆转储和快照,以查看对象和类在内存中的外观。我发现在我的CXF / JAXB(wsdl2java)生成的类中使用的XML模式中的一些枚举在取消部署后仍然存在。根据我的堆转储,它看起来像对象绑定到Map。免责声明:我承认我仍然有点整理绿色和跟踪对象的调用树在Java中可能具有挑战性。

After I learned how to profile a Java application, I pointed the profiler at Tomcat and took some heap dumps and snapshots to see what the objects and classes looked like in memory. I discovered that some of the enumerations from my XML schema used in my CXF/JAXB (wsdl2java) generated classes were lingering after an undeployment. According to my heap dump it looks like the objects were tied to a Map. Disclaimer: I admit I'm still a little green with profiling and tracing an object's call tree can be challenging in Java.

另外我应该提到我甚至没有调用该服务,刚刚部署然后取消部署它。对象本身似乎是通过部署时从Spring发起的反射来加载的。我相信我遵循了在Spring中设置CXF服务的惯例。因此,我不能100%确定这是Spring / CXF,JAXB还是反射的错误。

Also I should mention that I didn't even invoke the service, just deployed then undeployed it. The objects themselves appeared to be loaded via reflection initiated from Spring on deployment. I believe I followed the convention for setting up a CXF service in Spring. So I'm not 100% sure if this is Spring/CXF, JAXB, or reflection's fault.

作为旁注:有问题的应用程序是使用的Web服务Spring / CXF和XML恰好是一个相当复杂的模式( NIEM 的扩展)。

As a side note: the application in question is a web service using Spring/CXF and the XML happens to be a rather complex schema (an extension of NIEM).

推荐答案

如果你想确保不造成泄漏,你必须做以下事情:

If you want to make sure not to cause leaks you have to do the following:


  • 确保您的Web应用程序不使用Web容器共享库中的任何Java类。如果您有任何共享库,请确保没有对这些库中对象的强引用

  • 避免使用静态变量,尤其是对于HashTable,Sets等Java对象。如果需要to,确保你调用remove来释放带有地图,列表的对象......

这里也是一篇很好的文章ThreadLocal和MemoryLeaks - http:// blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

Here is also a good article on ThreadLocal and MemoryLeaks - http://blog.arendsen.net/index.php/2005/02/22/threadlocals-and-memory-leaks-revisited/

这篇关于有没有办法避免Tomcat中的部署内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆