Tomcat8内存泄漏
Tomcat8 memory leak
当我尝试在 Java 8 上停止 tomcat8 时,出现了一些内存泄漏错误:
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40)
23-Jan-2015 08:18:10.202 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-5-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread
23-Jan-2015 08:18:10.205 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [com.util.ThreadLocalProperties] (value [com.util.ThreadLocalProperties@2fafda6e]) and a value of type [java.util.Properties] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
class ThreadLocalProperties 是:
public class ThreadLocalProperties extends Properties {
private static final long serialVersionUID = -4260632266508618756L;
private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return new Properties();
}
};
public ThreadLocalProperties(Properties properties) {
super(properties);
}
@Override
public String getProperty(String key) {
String localValue = localProperties.get().getProperty(key);
return localValue == null ? super.getProperty(key) : localValue;
}
@Override
public Object setProperty(String key, String value) {
return localProperties.get().setProperty(key, value);
}
public ThreadLocal<Properties> getThreadLocal() {
return localProperties;
}
}
我这样开始和停止它:
@WebListener()
public class GeneralListener implements ServletContextListener {
ThreadLocalProperties threadLocalProperties = new ThreadLocalProperties(System.getProperties());
@Override
public void contextDestroyed(ServletContextEvent arg0) {
threadLocalProperties.getThreadLocal().remove();
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.setProperties(threadLocalProperties);
}
}
为什么我会收到所有这些内存泄漏错误?同样,当我 运行 关机时,它并没有关闭,我必须手动终止进程。
怎么了?
我认为你的问题类似于this。当您重新部署该应用程序时,apache 会在 system.gc();
不起作用的地方以增量方式将其部署到自身,并且在开发阶段进行几次重新部署后,永久生成的 space 已满,您会收到内存泄漏错误。
请在几次重新部署后继续重新启动您的服务器,以便通过重新启动清除 PermGen space。
或
a 你也可以通过更改server.xml中的PermGen space来解决。
请访问 here.
希望对您有所帮助。
没有什么可担心的。这是一个标准消息 tomcat 当它检测到应用程序已经启动它自己的 Thread
或创建一个 ThreadLocal
时输出。如果您在关闭时终止线程并在不再需要时删除 threadlocals,那么就不会有问题。
Why would I get all this memory leaks errors? as well, when I run
shutdown, it doesn't shut it down, I have to manually kill the
process.
我已经看到这种行为,当应用程序启动 ScheduledExecutor
(但任何其他 Thread
/TheadPool
时都会发生这种情况)并且没有关闭它contextDestroyed
。因此,请检查您是否在 application/server 停止时关闭您的线程。
现在解决您的具体问题 为什么服务器不停止:
JDBC 驱动程序在 JVM 中注册为单例,并与所有 Web 应用程序共享。更多信息 here. The best solution to your problem is to move the MySQL driver in Tomcat's /lib
folder. If you cannot do that you can try this 但它更像是 hack 而不是真正的解决方案。
当我尝试在 Java 8 上停止 tomcat8 时,出现了一些内存泄漏错误:
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142)
com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:40)
23-Jan-2015 08:18:10.202 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [pool-5-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread
23-Jan-2015 08:18:10.205 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [com.util.ThreadLocalProperties] (value [com.util.ThreadLocalProperties@2fafda6e]) and a value of type [java.util.Properties] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
class ThreadLocalProperties 是:
public class ThreadLocalProperties extends Properties {
private static final long serialVersionUID = -4260632266508618756L;
private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return new Properties();
}
};
public ThreadLocalProperties(Properties properties) {
super(properties);
}
@Override
public String getProperty(String key) {
String localValue = localProperties.get().getProperty(key);
return localValue == null ? super.getProperty(key) : localValue;
}
@Override
public Object setProperty(String key, String value) {
return localProperties.get().setProperty(key, value);
}
public ThreadLocal<Properties> getThreadLocal() {
return localProperties;
}
}
我这样开始和停止它:
@WebListener()
public class GeneralListener implements ServletContextListener {
ThreadLocalProperties threadLocalProperties = new ThreadLocalProperties(System.getProperties());
@Override
public void contextDestroyed(ServletContextEvent arg0) {
threadLocalProperties.getThreadLocal().remove();
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.setProperties(threadLocalProperties);
}
}
为什么我会收到所有这些内存泄漏错误?同样,当我 运行 关机时,它并没有关闭,我必须手动终止进程。
怎么了?
我认为你的问题类似于this。当您重新部署该应用程序时,apache 会在 system.gc();
不起作用的地方以增量方式将其部署到自身,并且在开发阶段进行几次重新部署后,永久生成的 space 已满,您会收到内存泄漏错误。
请在几次重新部署后继续重新启动您的服务器,以便通过重新启动清除 PermGen space。
或
a 你也可以通过更改server.xml中的PermGen space来解决。 请访问 here.
希望对您有所帮助。
没有什么可担心的。这是一个标准消息 tomcat 当它检测到应用程序已经启动它自己的 Thread
或创建一个 ThreadLocal
时输出。如果您在关闭时终止线程并在不再需要时删除 threadlocals,那么就不会有问题。
Why would I get all this memory leaks errors? as well, when I run shutdown, it doesn't shut it down, I have to manually kill the process.
我已经看到这种行为,当应用程序启动 ScheduledExecutor
(但任何其他 Thread
/TheadPool
时都会发生这种情况)并且没有关闭它contextDestroyed
。因此,请检查您是否在 application/server 停止时关闭您的线程。
现在解决您的具体问题 为什么服务器不停止:
JDBC 驱动程序在 JVM 中注册为单例,并与所有 Web 应用程序共享。更多信息 here. The best solution to your problem is to move the MySQL driver in Tomcat's /lib
folder. If you cannot do that you can try this 但它更像是 hack 而不是真正的解决方案。