Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有没有办法避免Tomcat中的未部署内存泄漏?_Java_Spring_Tomcat_Memory Leaks_Jaxb - Fatal编程技术网

Java 有没有办法避免Tomcat中的未部署内存泄漏?

Java 有没有办法避免Tomcat中的未部署内存泄漏?,java,spring,tomcat,memory-leaks,jaxb,Java,Spring,Tomcat,Memory Leaks,Jaxb,这个问题适用于任何曾经测试过Tomcat manager中的“查找泄漏”按钮并得到如下结果的人: 以下web应用程序已停止(重新加载、取消部署),但它们以前运行的类仍加载到内存中,从而导致内存泄漏(使用探查器确认): /泄漏的应用程序名称 我假设这与频繁重新部署时经常出现的“Perm Gen space”错误有关 所以我在部署jconsole时看到的是,我加载的类从2k到5k。然后,你会认为取消部署会使它们下降到2k,但它们仍然保持在5k 我还尝试使用以下JVM选项: -XX:+CMSClass

这个问题适用于任何曾经测试过Tomcat manager中的“查找泄漏”按钮并得到如下结果的人:

以下web应用程序已停止(重新加载、取消部署),但它们以前运行的类仍加载到内存中,从而导致内存泄漏(使用探查器确认):
/泄漏的应用程序名称

我假设这与频繁重新部署时经常出现的“Perm Gen space”错误有关

所以我在部署jconsole时看到的是,我加载的类从2k到5k。然后,你会认为取消部署会使它们下降到2k,但它们仍然保持在5k

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

-XX:+CMSClassUnloadingEnabled-XX:+UseConMarkSweepGC-XX:+CMSClassSweepInEnabled

我确实看到Perm Gen使用的空间量有很小的下降,但并没有达到我的预期,加载的类数也没有下降

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

Tomcat版本输出:

服务器版本:ApacheTomcat/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恰好是一个相当复杂的模式(XML的扩展)。

Tomcat 7应该在这方面有所改进。请参阅标题为“不再泄漏”的部分

他们相信他们现在可以处理由web应用程序引起的大量内存泄漏。不幸的是,它仍处于测试阶段


除此之外,我可以说我也有过同样的经历,还没有找到解决办法。部署通常需要在之后重新启动Tomcat。我不知道谁是罪魁祸首:我的web应用程序、Tomcat、Hibernate、Tapestry或其中的几个。

如果要确保不造成泄漏,必须执行以下操作:

  • 确保web应用程序不使用web容器共享库中的任何java类。如果有任何共享库,请确保这些库中的对象没有强引用
  • 避免使用静态变量,尤其是在HashTable、Set等java对象上。如果需要,请确保调用remove来释放带有映射、列表等的对象

这里还有一篇关于ThreadLocal和MemoryLeaks的好文章-

好信息!我尝试在没有任何第三方或共享LIB的情况下制作一个非常简单的应用程序,但没有看到与我上面概述的相同的症状。唯一的问题是,使用第三方LIB时,“真实世界”的应用程序可能会在某些地方出现内存泄漏。所以我想这一切都取决于开发人员。我相信我们都可以做出改进:Tomcat、我们的应用程序、库……有人知道动态字节码生成的效果吗,因为许多XML序列化程序、Hibernate和Tapestry都在使用动态字节码生成?这些库是否正确卸载?好的,我匆忙地说我没有看到相同的症状。也许我的测试应用程序太小了,没人注意到。我使用Tomcat示例应用程序进行了测试,再次看到PermGen已满,加载的类在取消部署后从未返回到基线。我知道PermGen用于存储有关加载类的元数据。因此,我认为取消部署应该会导致Tomcat删除应用程序的类引用,GC应该清除它们,并将它们的元数据放上去,对吗?即使我的类包含对其他类的强引用,当Tomcat卸载父类时,它们难道不应该消亡吗?很抱歉,经过更多的研究和分析速成课程后,我意识到我把类卸载与对象销毁混淆了。当我从Tomcat升级部署应用程序时,我希望看到类数减少。请看我关于这个问题的最新情况。另外,当我点击“查找漏洞”时,在取消部署示例应用程序后,它没有报告任何内容。