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

查看:26
本文介绍了有没有办法避免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

我认为这与频繁重新部署时经常遇到的永久代空间"错误有关.

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 模式中的一些枚举在取消部署后仍然存在.根据我的堆转储,看起来对象被绑定到地图.免责声明:我承认我对在 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.

附带说明:所讨论的应用程序是使用 Spring/CXF 的 Web 服务,而 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 对象上.如果需要,请确保调用 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天全站免登陆