您的位置:首页 > 编程语言 > Java开发

【Developer Log】Java1.8在J2EE中疑似leak的修正

2015-12-04 16:45 399 查看
在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));


相关链接:开发日志
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: