Threads are going to be renewed over time to try and avoid a probable memory leak.
记录一次内存泄漏问题的解决问题现象:启动tomcat后,过几个小时,线上的工程就会停止运行了,日志里面就会报下面这样的错误13-Aug-2019 12:51:27.248 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The ..
记录一次内存泄漏问题的解决
问题现象:启动tomcat后,过几个小时,线上的工程就会停止运行了,日志里面就会报下面这样的错误
13-Aug-2019 12:51:27.248 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4a9cfa60]) and a value of type [com.daichao.loans.api.common.AuthenticationType] (value [TOKEN]) 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.
这个是由于类加载器泄漏导致的的,从上面的问题可以看出来当应用结束的时候,想释放AuthenticationType,但是却释放不了,为什么释放不了呢?
先看代码:
先在LoginUtils里面定义了一个ThreadLocal
public static final ThreadLocal<AuthenticationType> authenticationType
= new ThreadLocal<AuthenticationType>();
再到SystemController类里设置值
LoginUtils.authenticationType.set(authenticationType);
最后再到MyRealm里取值
AuthenticationType authTypeClass = LoginUtils.authenticationType.get();
tomcat有一个线程池,当有外部请求来的时候,会从线程池里面取出一个线程来处理请求,ThradLocal引用了AuthenticationType,线程对ThradLocal设值,相当于将AuthenticationType绑定到了这个线程,当应用结束了,想去回收AuthenticationType的classloader,即使已经没有其他地方对AuthenticationType的引用了,但线程还没有结束,这个线程还对AuthenticationType有引用,tomcat回收资源的时候,发现AuthenticationType回收不了,就会出现内存泄漏的警告。
最后的解决方法是:当应用结束的时候手动释放ThreadLocal里面的AuthenticationType
try{
AuthenticationType authTypeClass = LoginUtils.authenticationType.get();
}finally{
LoginUtils.authenticationType.remove();
}
参考文章:https://blog.csdn.net/u010619243/article/details/62899033
更多推荐



所有评论(0)