Web应用程序和Tomcat 7内存泄漏

时间:2012-04-24 14:43:11

标签: java hibernate quartz-scheduler tomcat7 visualvm

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

  

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

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

没有部署的Tomcat启动时

http://img15.imageshack.us/img15/4441/tomcatstartup.jpg

我的网络应用涉及:

  • Quartz 1.8.5
  • Hibernate 3.6.3
  • JAXB 2.2.4
  • Salesforce API
  • 的log4j

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

所以我注意到它抱怨Quartz,我也在某处阅读关闭servlet destroy的Hibernate Session Factory。

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

  

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

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

然而,当我使用“发现泄漏”时,它仍然抱怨同样的事情

  

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

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

所以我的问题是 - 我还应该注意什么?和/或如何更好地使用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驱动程序的问题 - 我需要它用于我的网络应用程序,似乎我有2个基于以下答案的解决方案:To prevent a memory leak, the JDBC Driver has been forcibly unregistered

  1. 将mysql-connector jar放入tomcat / lib
  2. 在contextDestroyed中手动取消注册驱动程序。
  3. 我应该采用哪种方式,最佳做法是什么?

1 个答案:

答案 0 :(得分:4)

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

与在Quartz doc中一样,尝试使用:

 <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>

希望这可以帮到你。