【问题标题】:Web app and Tomcat 7 Memory LeakWeb 应用程序和 Tomcat 7 内存泄漏
【发布时间】:2012-05-05 05:31:17
【问题描述】:

我正在(测试)在 Tomcat 7 中运行我的网络应用程序并使用他们的“查找泄漏”按钮,当然当我停止/取消部署时它会抱怨内存泄漏。

以下 Web 应用程序已停止(重新加载、取消部署), 但是它们之前运行的类仍然加载到内存中,因此 导致内存泄漏(使用分析器确认): /LeakyWebApp

所以我使用了 Java VisualVM(我第一次尝试)

在没有部署的情况下启动 Tomcat: http://img15.imageshack.us/img15/4441/tomcatstartup.jpg

我的网络应用涉及:

  • 石英 1.8.5
  • 休眠 3.6.3
  • JAXB 2.2.4
  • Salesforce API
  • log4j

部署后立即: http://img850.imageshack.us/img850/2951/tomcatafterdeployment.jpg

所以我注意到它抱怨 Quartz,我还阅读了某处以在 servlet 销毁时关闭 Hibernate Session Factory。

在停止/取消部署时,Visual VM 确实显示 Quartz 线程已停止,但 tomcat 日志显示

“似乎启动了一个名为 ... 的线程,但未能停止它”

所以我创建了一个新的 ServletContextListener 并在 contextDestroyed 上调用 Quartz 工厂调度程序以关闭并在 Hibernate Session Factory 上调用 close。并进行另一次部署/取消部署,tomcat 日志不再抱怨上述 Quartz 线程问题。

但是,当我使用“查找泄漏”时,它仍然抱怨同样的事情

以下 Web 应用程序已停止(重新加载、取消部署), 但是它们之前运行的类仍然加载到内存中,因此 导致内存泄漏(使用分析器确认): /LeakyWebApp

然后我发现另一个关于 JDBC 驱动程序的抱怨(我的战争中有 mysql 连接器 jar),所以我尝试删除它,来自 tomcat 日志的抱怨消失了,但“查找泄漏”仍然说我的网络应用程序有同样的事情内存泄漏

所以我的问题是 - 我还应该看什么?和/或如何更好地使用 Visual VM 来检测正在发生的事情?

谢谢

编辑: 我根据 David Feitosa 的帖子解决了 Quartz 的问题,我错过了

 <init-param>
     <param-name>wait-on-shutdown</param-name>
     <param-value>true</param-value>
 </init-param>

来自 web.xml 中的 Quartz 属性。

但是 - 我的 JDBC 驱动程序仍然存在问题 - 我的 Web 应用程序需要它,并且似乎我有 2 个基于以下答案的解决方案:To prevent a memory leak, the JDBC Driver has been forcibly unregistered

  1. 将mysql-connector jar放到tomcat/lib中
  2. 在 contextDestroyed 中手动取消注册驱动程序。

我应该走哪条路,最好的做法是什么?

【问题讨论】:

    标签: java hibernate quartz-scheduler tomcat7 visualvm


    【解决方案1】:

    我在这类 Web 应用程序中发现的大多数内存泄漏问题都与 Quartz 有关。为了解决这个问题,尝试使用合适的 Quartz Servlet 来初始化工厂:http://quartz-scheduler.org/api/2.0.0/org/quartz/ee/servlet/QuartzInitializerServlet.html

    就像在 Quartz 文档中一样,尝试使用:

     <servlet>
         <servlet-name>
             QuartzInitializer
         </servlet-name>
         <display-name>
             Quartz Initializer Servlet
         </display-name>
         <servlet-class>
             org.quartz.ee.servlet.QuartzInitializerServlet
         </servlet-class>
         <load-on-startup>
             1
         </load-on-startup>
         <init-param>
             <param-name>config-file</param-name>
             <param-value>/some/path/my_quartz.properties</param-value>
         </init-param>
         <init-param>
             <param-name>shutdown-on-unload</param-name>
             <param-value>true</param-value>
         </init-param>
         <init-param>
             <param-name>wait-on-shutdown</param-name>
             <param-value>true</param-value>
         </init-param>
         <init-param>
             <param-name>start-scheduler-on-load</param-name>
             <param-value>true</param-value>
         </init-param>
     </servlet>
    

    希望对你有帮助。

    【讨论】:

    • 谢谢,我只是错过了“等待关机”属性,它解决了这个问题。但是,我的 JDBC 驱动程序“[leakyApp] 注册 JDBC 驱动程序但未能取消注册”仍然存在问题 - 这是因为我的 Web 应用程序中有 mysql-connector-java.jar,但我可以不删除它,因为我需要它 - 我可以为这个问题做些什么?
    • 不高兴,我还没有驱动程序问题的线索。如果我找到了,我会回到这里。您是否可以查看您的服务器文档?也许在 Tomcat 或 JBoss 中使用 DataSource 对象可以解决您的驱动问题。
    • 您好,我也面临同样的问题,但是如何将此 Servlet 添加到我的应用程序中。我可以创建新的 servlet 类,并将 war 文件部署到 tomcat 中。会成功吗? ...
    猜你喜欢
    • 2014-04-12
    • 2014-04-05
    • 1970-01-01
    • 2012-04-02
    • 2012-11-09
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多