在Tomcat中重新部署应用程序时发生内存泄漏 [英] Memory leak when redeploying application in Tomcat

查看:166
本文介绍了在Tomcat中重新部署应用程序时发生内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在tomcat中重新部署我的应用程序时,我遇到以下问题:

When I redeploy my application in tomcat, I get the following issue:

 The web application [] created a ThreadLocal with key of type
 [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@10d16b])
 and a value of type [com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty]
(value [com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty@1a183d2]) but 
 failed to remove it when the web application was stopped. 
 This is very likely to create a memory leak.

此外,我在我的应用程序中使用ehcache。这似乎也会导致以下异常。

Also, am using ehcache in my application. This also seems to result in the following exception.

     SEVERE: The web application [] created a ThreadLocal with key of type [null] 
     (value [com.sun.xml.bind.v2.ClassFactory$1@24cdc7]) and a value of type [java
     .util.WeakHashMap... 

ehcache似乎创建了一个弱哈希映射,我得到的消息是这很可能会造成内存泄漏。

The ehcache seems to create a weak hash map and I get the message that this is very likely to create a memory leak.

我在网上搜索并找到了这个,
http://jira.pentaho.com/browse/PRD-3616 但我无法访问服务器。

I searched over the net and found this, http://jira.pentaho.com/browse/PRD-3616 but I dont have access to the server as such.

请告诉我如果这些警告有任何功能影响或者可以忽略吗?我在tomcat管理器中使用了查找内存泄漏选项,它说没有发现内存泄漏

Please let me know if these warnings have any functional impact or can they be ignored? I used the "Find Memory leaks" option in tomcat manager and it says "No memory leaks found"

推荐答案

重新部署时应用程序,Tomcat创建一个新的类加载器。旧的类加载器必须是垃圾回收,否则会导致permgen内存泄漏。

When you redeploy your application, Tomcat creates a new class loader. The old class loader must be garbage collected, otherwise you get a permgen memory leak.

Tomcat无法检查垃圾收集是否有效,但它知道几个常见的失败点。如果webapp类加载器设置一个 ThreadLocal ,其实例的类由webapp类加载器本身加载,则servlet线程将保存对该实例的引用。这意味着类加载器不会被垃圾收集。

Tomcat cannot check if the garbage collection will work or not, but it knows about several common points of failures. If the webapp class loader sets a ThreadLocal with an instance whose class was loaded by the webapp class loader itself, the servlet thread holds a reference to that instance. This means that the class loader will not be garbage collected.

Tomcat做了很多这样的检测,参见这里有更多信息。清理线程本地很困难,你必须在每个线程中的 ThreadLocal 上调用 remove()从。访问。实际上,在您多次重新部署Web应用程序时,这在开发过程中非常重要。在生产中,您可能不会重新部署,因此可以忽略它。

Tomcat does a number of such detections, see here for more information. Cleaning thread locals is difficult, you would have to call remove() on the ThreadLocal in each of the threads that is was accessed from. In practice this is only important during development when you redeploy your web app multiple times. In production, you probably do not redeploy, so this can be ignored.

要真正找出定义线程本地的实例,您必须使用分析器。例如, JProfiler 中的堆步行者(免责声明:我的公司开发JProfiler)将帮助您找到那些线程本地。选择报告的值类(com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty或com.sun.xml.bind.v2.ClassFactory)并显示累积的传入引用。其中一个是 java.lang.ThreadLocal $ ThreadLocalMap $ Entry 。选择该传入引用类型的引用对象,然后切换到分配视图。您将看到实例已分配的位置。根据这些信息,您可以决定是否可以采取相关措施。

To really find out which instances define the thread locals, you have to use a profiler. For example the heap walker in JProfiler (disclaimer: my company develops JProfiler) will help you to find those thread locals. Select the reported value class (com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty or com.sun.xml.bind.v2.ClassFactory) and show the cumulated incoming references. One of those will be a java.lang.ThreadLocal$ThreadLocalMap$Entry. Select the referenced objects for that incoming reference type and switch to the allocations view. You will see where the instance has been allocated. With that information you can decide whether you can do something about it or not.

这篇关于在Tomcat中重新部署应用程序时发生内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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