在Java 8的Eclipse开发环境环境中,如果我们停止Tomcat 8(例如修改代码,保存,会引发tomcat的自动重启)。在停止过程过程中,我们可能会看到下面的一些错误。
Thread.sleep()的疑似内存泄漏
这个问题其实倒不是很关键,不会真的有泄漏,只是代码洁癖。下面是代码片段:
private boolean isRunning;
public void close(){
isRunning = false;
}
@Override
public void start() {
isRunning = true;
start();
}
@Override
public void run() {
while(isRunning){
try{
Thread.sleep(1000);
myAction();
}catch(Exception e){
e.printStackTrace();
}
}
}
如果我们在介绍destroy()时调用实例的close(),会报下面的错误:
十二月 04, 2015 10:59:30 上午 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
警告: The web application [mywebapp] appears to have started a thread named [Thread-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Thread.sleep(Native Method)
这是因为Thread.sleep(1000)挂起,无法马上结束导致。土方法是在destroy()调用close()之后,又一个延迟,例如也sleep一个时间,确保线程中的run()能够退出,另一个方式就是使用Thread.interrupt()强制从Thread.sleep()中退出,代码如下:
private volatile boolean isRunning;
public void close(){
isRunning = false;
this.interrupt();
}
@Override
public void start() {
isRunning = true;
start();
}
@Override
public void run() {
while(isRunning){
try{
Thread.sleep(1000);
if(isRunning)
myAction();
}catch(Exception e){
if(isRunning) //强制Interrupt会有异常java.lang.InterruptedException: sleep interrupted,马上退出
e.printStackTrace();
}
}
}
推荐参考:https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
MySQL数据库连接关闭的疑似泄漏
在web app结束之际,关闭数据库连接池的各条连接,报下面错误:
十二月 04, 2015 11:27:08 上午 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc 警告: The web application [mywebapp] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forciblyunregistered. 十二月 04, 2015 11:27:08 上午 org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads 警告: The web application [mywebapp] 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(Unknown Source) com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43) |
有两个错误,一个说没有unregister,一个说AbandonedConnectionCleanupThread的错,实际上这个也没有太大的问题,但是如果有报错洁癖的,可以将代码修订如下:
try {
com.mysql.jdbc.AbandonedConnectionCleanupThread.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
myCloseAllConnectionsInPool(); //关闭连接池的各个Connection
DriverManager.deregisterDriver(DriverManager.getDriver(jdbcUrl));
相关链接:开发日志