在 Tomcat 中重新部署应用程序时发生内存泄漏

     2023-02-25     161

关键词:

【中文标题】在 Tomcat 中重新部署应用程序时发生内存泄漏【英文标题】:Memory leak when redeploying application in Tomcat 【发布时间】:2011-12-08 22:50:36 【问题描述】:

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

 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。这似乎也导致了以下异常。

     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 似乎创建了一个弱哈希映射,我收到消息说这很可能会造成内存泄漏。

我在网上搜索了一下,发现了这个, http://jira.pentaho.com/browse/PRD-3616 但我无权访问服务器。

请让我知道这些警告是否对功能有任何影响,或者可以忽略它们吗?我在 tomcat 管理器中使用了“查找内存泄漏”选项,它显示“未发现内存泄漏”

【问题讨论】:

警告意味着您在不重新启动 Tomcat 的情况下重新部署应用程序的能力受到限制。 Webapps 长期以来一直受到这种类型的内存泄漏的困扰。除非您重新部署应用程序,否则它们不会产生任何影响。我不知道,但我怀疑 Tomcat 输出中的这些消息(它们会在一两年内再次出现)对框架构建者施加压力,要求它们在重新启动后开始正确清理。 【参考方案1】:

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

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

Tomcat 会进行许多此类检测,请参阅here for more information。清理线程局部变量很困难,您必须在访问的每个线程中的ThreadLocal 上调用remove()。实际上,这仅在您多次重新部署 Web 应用程序的开发过程中很重要。在生产中,您可能不会重新部署,因此可以忽略。

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

【讨论】:

如我所见,JProfiler 似乎不是免费的开源解决方案。你能推荐一些其他的选择吗 @Raghav Eclipse 内存分析器也非常适合分析堆转储。 eclipse.org/mat【参考方案2】:

Mattias Jiderhamn 拥有出色的 6-part article 非常清楚地解释了有关类加载器泄漏的理论和实践。更好的是,他还发布了一个 jar 文件,我们可以将其包含在我们的 war 文件中。我在我的网络应用程序上尝试过,jar 文件就像一个魅力! jar 文件称为 classloader-leak-prevention.jar。使用它就像将它添加到我们的 web.xml 一样简单

<listener>
  <listener-class>se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor</listener-class>
</listener>

然后将其添加到我们的 pom.xml 中

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.15.2</version>
</dependency>

有关详细信息,请参阅 project home page hosted on GitHub 要么 Part 6 of his article

【讨论】:

【参考方案3】:

创建线程而不正确清理它们最终会耗尽您的内存 - 去过那里,做到了。

那些仍然想知道快速解决方案/解决方法的人,可以去以下:

如果运行独立的 tomcat,请终止 javaw.exe 或承载它的进程。 如果从 Eclipse 运行,请终止 eclipse.exe 和 java.exe 或封闭进程。 仍未解决,检查任务管理器,可能导致此问题的进程将显示为最高内存 用法 - 做你的分析并杀死它。

您应该很好地重新部署这些东西并继续进行,而不会出现内存问题。

【讨论】:

【参考方案4】:

我猜你可能已经看到了,但以防 ehcache 文档向 put the lib in tomcat and not in WEB-INF/lib 推荐。

【讨论】:

【参考方案5】:

我建议在 ServletRequestListener 中初始化 thread locals。

ServletRequestListener 有两种方法:一种用于初始化,一种用于销毁。

这样,您可以清理您的ThreadLocal。示例:

public class ContextInitiator implements ServletRequestListener 
    @Override
    public void requestInitialized(ServletRequestEvent sre) 
        context = new ThreadLocal<ContextThreadLocal>() 
            @Override
            protected ContextThreadLocal initialValue() 
                ContextThreadLocal context = new ContextThreadLocal();
                return context;
            
        ;
        context.get().setRequest(sre.getServletRequest());
    
    @Override
    public void requestDestroyed(ServletRequestEvent sre) 
        context.remove();
    

web.xml:

<listener>
    <listener-class>ContextInitiator</listener-class>
</listener>

【讨论】:

停止/重新部署时 Tomcat 7+ 内存泄漏。弹簧数据,JPA,休眠,MySQL

...间】:2017-12-1617:32:10【问题描述】:我在停止/重新部署应用程序时遇到了tomcat内存泄漏问题。它说以下Web应用程序已停止(重新加载、取消部署),但它们的以前运行的类仍然加载到内存中,从而导 查看详情

内存泄漏 - Tomcat、Spring MVC

...谷歌搜索过***,但找不到答案。我有一个Maven、SpringMVCWeb应用程序,它连接到MySQL数据库。问题是每次我重新部署(停止、取消部署然后部署)我的war文件时,我都会在日志文件中得到以下异常:SEVERE:Thewebapplication[/ 查看详情

Tomcat 8 内存泄漏

...:07【问题描述】:我正在使用Spring/SpringBoot/MySQL开发JavaWeb应用程序并将其部署到Tomcat8。在TomcatWeb应用程序管理器中,我单击Reload按钮,成功重新部署后-FindLeaks按钮并显示以下消息:Thefollowingwebapplicationswerestopped( 查看详情

Tomcat 7 中的内存泄漏 Grails 应用程序

】Tomcat7中的内存泄漏Grails应用程序【英文标题】:MemoryLeakGrailsapplicationinTomcat7【发布时间】:2014-04-1217:32:11【问题描述】:我在生产中有一个grails(v2.1.5)应用程序,它工作正常,我可以毫无问题地重新部署,但我已经更新了应用... 查看详情

重新部署时 Google Cloud Pub Sub 内存泄漏(基于 Netty)

...ttybased)【发布时间】:2020-03-1114:00:36【问题描述】:我的tomcat网络服务使用realtimedevelopernotificationsforAndroid,这需要GoogleCloudPubSub。它工作完美,所有通知都会立即收到。唯一 查看详情

在IOS中使用web服务时发生NSURLSession内存泄漏

...4-02-2813:40:42【问题描述】:我正在构建一个使用Web服务的应用程序,并从我使用NSURLSession和NSURLSessionDataTask的Web服务获取信息。我现在处于内存测试阶段,我发现NSURLSession 查看详情

在多个窗口中使用 WPF WebBrowser 控件时发生内存泄漏

】在多个窗口中使用WPFWebBrowser控件时发生内存泄漏【英文标题】:MemoryleakwhenusingWPFWebBrowsercontrolinmultiplewindows【发布时间】:2011-01-0508:58:29【问题描述】:我正在开发一个使用WPFWebBrowser控件(System.Windows.Controls.WebBrowser)的项目。... 查看详情

tomcat 没有在内存不足错误时生成 hprof 文件

...间】:2014-07-3122:07:18【问题描述】:我在tomcat中部署的Web应用程序中存在一些内存泄漏问题。为了找到根本原因,我通过设置启用了HeapDumpOnOutOfMemory错误:-XX:-HeapDumpOnOutOfMemoryError-XX:He 查看详情

OpenCv - 从网络摄像头捕获帧时发生内存泄漏

...时间】:2015-01-0404:54:07【问题描述】:我正在编写一个C应用程序,它使用OpenCv从网络摄像头捕获图像,然后将图像保存到文件中。它在针对OpenCv2.3.1-11的RaspianOSWheezy上运行。如果我只是像这样打开和关闭网络摄像头,就没有内存... 查看详情

Tomcat 修复内存泄漏?

...问题描述】:我正在使用6.0.20我在服务器上运行了许多Web应用程序,随着时间的推移,大约3天,服务器需要重新启动,否则服务器会崩溃并无响应。我对JVM有以下设置:-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=c:\\tomcat\\Websites\\ 查看详情

导航时发生 Javascript 内存泄漏

...ing【发布时间】:2014-12-1110:38:04【问题描述】:当我在web应用程序的网页之间导航时进行持续时间测试时,我遇到了巨大的内存增加。这不是一个单页应用程序,所以我正在导航:window.location.href="linkToOtherPage.html";这应该... 查看详情

内存溢出和内存泄漏

...        1.常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。    2.偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过... 查看详情

什么是内存泄漏

...分配和释放内存。然而,事实并非如此简单,因为在Java应用程序中经常发生内存泄漏。本教程说明了什么是内存泄漏,为什么会发生,以及如何防止它们。1.什么是内存泄漏?内存泄漏的定义:对象不再被应用程序使用,但是垃... 查看详情

验证可执行文件的 Authenticode 签名时发生内存泄漏?

】验证可执行文件的Authenticode签名时发生内存泄漏?【英文标题】:MemoryLeakwhileverifyingAuthenticodeSignatureofExecutables?【发布时间】:2011-05-0309:26:08【问题描述】:我正在使用WinVerifyTrust来验证某些Windows可执行文件的有效性,该函数... 查看详情

Observable 源对象被破坏时的内存泄漏

...阅observable时会发生什么,那么这个observable的来源不再在应用程序中使用?有没有内存泄漏?我有FormArray,其中有一些FormGroup。我订阅了每个FormGroup.valueChang 查看详情

初始化推送通知时发生奇怪的 ionic 内存泄漏导致冻结

...这几天我遇到了一些非常奇怪的记忆问题。问题是,有时应用程序会卡住并开始非常快速地增加内存使用量,直到崩溃。当内存增加时,应用程序完全冻结。经过一些调试,我发现此 查看详情

c语言中啥叫内存泄露?

...以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们... 查看详情

java提高篇——简单介绍java的内存泄漏

阅读目录什么是内存泄漏?为什么会发生内存泄漏?如何预防内存泄漏?  java最明显的一个优势就是它的内存管理机制。你只需简单创建对象,java的垃圾回收机制负责分配和释放内存。然而情况并不像想像的那么简单,因为在Java... 查看详情