【发布时间】:2016-02-04 21:42:51
【问题描述】:
我收到来自 tomcat 的警告
Web 应用程序似乎启动了一个名为 [Abandoned 连接清理线程],但未能阻止它。这是非常 可能会造成内存泄漏。
这是一个已知问题,我通过调用解决了
com.mysql.jdbc.AbandonedConnectionCleanupThread.shutdown();
在MyServler.destroy()。这工作正常,除了从未使用过的 servlet。对于这样的 servlet,init 和 destroy 都不会被调用。但是,AbandonedConnectionCleanupThread 开始了!通过修改它的来源,我可以找到:
com.mysql.jdbc.AbandonedConnectionCleanupThread.start(AbandonedConnectionCleanupThread.java:19)
com.mysql.jdbc.NonRegisteringDriver.<clinit>(NonRegisteringDriver.java:106)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:383)
java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:373)
java.util.ServiceLoader$1.next(ServiceLoader.java:445)
java.sql.DriverManager$2.run(DriverManager.java:510)
java.sql.DriverManager$2.run(DriverManager.java:490)
java.security.AccessController.doPrivileged(Native Method)
java.sql.DriverManager.loadInitialDrivers(DriverManager.java:490)
java.sql.DriverManager.<clinit>(DriverManager.java:100)
org.apache.catalina.loader.JdbcLeakPrevention.clearJdbcDriverRegistrations(JdbcLeakPrevention.java:45)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.apache.catalina.loader.WebappClassLoader.clearReferencesJdbc(WebappClassLoader.java:1775)
org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClassLoader.java:1704)
org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java:1622)
org.apache.catalina.loader.WebappLoader.stop(WebappLoader.java:710)
org.apache.catalina.core.StandardContext.stop(StandardContext.java:4649)
org.apache.catalina.manager.ManagerServlet.undeploy(ManagerServlet.java:1365)
org.apache.catalina.manager.HTMLManagerServlet.undeploy(HTMLManagerServlet.java:563)
org.apache.catalina.manager.HTMLManagerServlet.doGet(HTMLManagerServlet.java:123)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Thread.java:745)
在堆栈跟踪中没有我的代码的痕迹,所以我想知道如何防止它?或者,如何在不调用 MyServlet.destroy() 的情况下关闭线程?
上面的stacktrace来自tomcat6,但是tomcat7也有泄漏。
【问题讨论】:
-
您不能注册
ServletContextListener以在卸载 Web 应用程序(而不是单个 servlet)时收到通知吗? -
@biziclop 我想,我可以。但是,我不知道如何从
ServletContext访问我的 servlet ot 罪魁祸首线程。 -
为什么需要访问 servlet?
AbandonedConnectionCleanupThread.shutdown()是否仅适用于 servlet?还是我误读了什么? -
@biziclop 这是一个静态方法,属于一个类由servlet的类加载器加载。所以我需要像
getTheRightClassLoader().loadClass("com.mysql.jdbc.AbandonedConnectionCleanupThread")这样的东西。也许servletContextEvent.getClass().getClassLoader()会,也许不会。也许我错过了一些东西。我会尝试ServletContextListener,除非给出更简单的解决方案。 -
简单地说:Web 应用程序就是您放入单个 WAR 文件中的所有内容。它可以包含 servlet、过滤器、侦听器、静态资源、JSP 文件,并且始终只包含一个
web.xml文件,您可以在其中定义所有这些如何组合在一起。
标签: java tomcat servlets memory-leaks