您的位置:首页 > 其它

在web项目中使用 ThreadLocal 要谨慎,使用不当容易造成内存溢出

2016-09-29 13:56 591 查看
这里使用的servlet容器是 tomcat

如果在web项目中,使用 ThreadLocal 不当,会造成 OutOfMemoryError。

说明原因前

1:先讲一下 ThreadLocal,Thead,ThreadLocalMap 三者之间的一个关系。(大家可以去看一下ThreadLocal的实现源码,可而参考我的另一篇文章点击查看

ThreadLocalMap 是 ThreadLocal 的一个内部类,一看是Map,保存数据的形式就是key value 形式的。

Thread类有一个成员变量 threadLocals,这个变量的数据类型是 ThreadLocal.ThreadLocalMap。threadLocals保存数据的key是ThreadLocal本身

2:tomcat线程池

tomcat启动的时候会创建一个线程池,配置如下

<Connector port="80" protocol="HTTP/1.1" maxThreads="600" minSpareThreads="100" maxSpareThreads="500" acceptCount="700"
connectionTimeout="20000" redirectPort="8443" />


maxThreads=”600” ///最大线程数

minSpareThreads=”100”///初始化时创建的线程数

maxSpareThreads=”500”///一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。

acceptCount=”700”//指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理

这里说一下为什么 如果在web项目中,使用 ThreadLocal 不当,会造成 OutOfMemoryError。

如果调用 ThreadLocal 的 set 方法 将一个对象放入Thread中的成员变量threadLocals 中,那么这个对象是永远不会被回收的,因为这个对象永远都被Thread中的成员变量threadLocals引用这。

如果想让垃圾收集器回收它,有两种方法

1:将该线程从tomcat线程池中去除,当一个线程被回收的时候何况它的成员变量呢,但是tomcat启动一般都会配置一个线程池进行优化,所有该方法不太现实。

2:调用 ThreadLocal 的 remove 方法 将对象从hread中的成员变量threadLocals 中删除掉。

设想如果将一个大对象放入threadLocals 中,并且还没有remove。那么就可能会造成OutOfMemoryError,如果不会造成OutOfMemoryError那么也很浪费java堆内存
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐