论坛首页 Java企业应用论坛

关于ThreadLocal的内存泄露

浏览 15872 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-07-05  
Spring 中用到了大量的ThreadLocal,也未见什么大问题,是否lz 多虑了。

另外个人一个小小见解:
一般容器会有个线程池之类的,可以说是固定了线程数量了,线程被重用了,ThreadLocal 的值也会被覆盖,这时gc就可以清理了。。
0 请登录后投票
   发表时间:2010-07-05  
看来没有几个真正搞清楚的,请看源代码吧。

ThreadLocal一定要用static类型的,否则内存泄露。
0 请登录后投票
   发表时间:2010-07-06  
threadlocal是一个weakhashmap

那么,threadlocal<you_instance>的you_instance又引用了threadlocal的话,会出现内存泄漏。

线程池的话,只会出现问题,线程不死,threadlocal里面的值不会被回收,存在一些风险,不会带来内存泄漏。
0 请登录后投票
   发表时间:2010-07-06  
欣赏lz看代码的精神和效果。
0 请登录后投票
   发表时间:2011-05-04  
引用
那么何时会“内存泄露”?当Thread长时间不结束,存在大量废弃的ThreadLocal,而又不再添加新的ThreadLocal(或新添加的ThreadLocal恰好和一个废弃ThreadLocal在map中命中)时。


楼主,你似懂非懂呀!你的意思是,如果存在强引用(或者是弱引用),那么在回收内存时不会清理弱引用,对吧。 呵呵,但是你想想,如果存在大量强引用的对象,你还想分配内存地址给你的对象,那会报“内存不够用”的异常,请您再发表这些言论时,为了避免误导大家,务必先做个实验验证!
0 请登录后投票
   发表时间:2011-05-04  
末了,为了说明白一点,再补充上次回复说一句: 报“内存不够”的异常,一般是您设计的问题,为什么要设计很多线程不停地跑,而且不等它们跑完就要加新的线程进来占用内存?这和你有能容纳1T个对象能力的内存,你创建1T个对象,这些对象都有强引用指向,所以都不能回收,你还要创建1T个对象,那都会报内存不够的异常。
0 请登录后投票
   发表时间:2011-05-05  
redhat 写道
引用
那么何时会“内存泄露”?当Thread长时间不结束,存在大量废弃的ThreadLocal,而又不再添加新的ThreadLocal(或新添加的ThreadLocal恰好和一个废弃ThreadLocal在map中命中)时。


楼主,你似懂非懂呀!你的意思是,如果存在强引用(或者是弱引用),那么在回收内存时不会清理弱引用,对吧。 呵呵,但是你想想,如果存在大量强引用的对象,你还想分配内存地址给你的对象,那会报“内存不够用”的异常,请您再发表这些言论时,为了避免误导大家,务必先做个实验验证!


ThreadLocal是弱引用的,但是map本身是强引用的,所以即使key被回收为null,value还在,另外,在很多threadlocal的应用中,value对象不再调用环境之外保留强引用,所以才会引起所谓“内存泄露”
0 请登录后投票
   发表时间:2011-05-05  
yangyi 写道
redhat 写道
引用
那么何时会“内存泄露”?当Thread长时间不结束,存在大量废弃的ThreadLocal,而又不再添加新的ThreadLocal(或新添加的ThreadLocal恰好和一个废弃ThreadLocal在map中命中)时。


楼主,你似懂非懂呀!你的意思是,如果存在强引用(或者是弱引用),那么在回收内存时不会清理弱引用,对吧。 呵呵,但是你想想,如果存在大量强引用的对象,你还想分配内存地址给你的对象,那会报“内存不够用”的异常,请您再发表这些言论时,为了避免误导大家,务必先做个实验验证!


ThreadLocal是弱引用的,但是map本身是强引用的,所以即使key被回收为null,value还在,另外,在很多threadlocal的应用中,value对象不再调用环境之外保留强引用,所以才会引起所谓“内存泄露”

看来要给你好好上一课了,map里的value,如果使用强引用,那么持续的往里面添加value,即使你外部程序对此value释放引用了,但是,你的map的key还没有,这样的map随着时间膨胀,不remove一些值的话,就会引起内存不够,这才是weakreferencemap使用的原因,当你程序的强引用指向此value断掉,那么应该map里自动断掉引用,回收此value,不管是weakmap还是softmap,都应该是对key的softreference或者weakrefrence的包装,试想下,如果程序运行过程中,你的value对象被回收了,那是多么悲哀的事情,程序不都是报nullpointexception了。
要知其然,才能明白所以然。
0 请登录后投票
   发表时间:2011-05-05  
redhat 写道
yangyi 写道
redhat 写道
引用
那么何时会“内存泄露”?当Thread长时间不结束,存在大量废弃的ThreadLocal,而又不再添加新的ThreadLocal(或新添加的ThreadLocal恰好和一个废弃ThreadLocal在map中命中)时。


楼主,你似懂非懂呀!你的意思是,如果存在强引用(或者是弱引用),那么在回收内存时不会清理弱引用,对吧。 呵呵,但是你想想,如果存在大量强引用的对象,你还想分配内存地址给你的对象,那会报“内存不够用”的异常,请您再发表这些言论时,为了避免误导大家,务必先做个实验验证!


ThreadLocal是弱引用的,但是map本身是强引用的,所以即使key被回收为null,value还在,另外,在很多threadlocal的应用中,value对象不再调用环境之外保留强引用,所以才会引起所谓“内存泄露”

看来要给你好好上一课了,map里的value,如果使用强引用,那么持续的往里面添加value,即使你外部程序对此value释放引用了,但是,你的map的key还没有,这样的map随着时间膨胀,不remove一些值的话,就会引起内存不够,这才是weakreferencemap使用的原因,当你程序的强引用指向此value断掉,那么应该map里自动断掉引用,回收此value,不管是weakmap还是softmap,都应该是对key的softreference或者weakrefrence的包装,试想下,如果程序运行过程中,你的value对象被回收了,那是多么悲哀的事情,程序不都是报nullpointexception了。
要知其然,才能明白所以然。

你说的都是对的,你仔细看我说的,和你说的矛盾吗?你为什么觉得要给我上一课,你懂的,别人不懂?
0 请登录后投票
   发表时间:2011-05-05  
yangyi 写道
那么何时会“内存泄露”?当Thread长时间不结束,存在大量废弃的ThreadLocal



存在大量废弃的ThreadLocal很有可能说明程序设计有问题吧?ThreadLocal一般是static的,只要类不被回收,那ThreadLocal也不会回收的啊,也就不存在废弃的说法了。

在finally中清空ThreadLocal中持有的对象引用就不会造成内存泄露

 

public class MyClass {

	private static final ThreadLocal threadLocal = new ThreadLocal();
	
	private Object value;

	public void myMethod() {
		try {
			threadLocal.set(value);
			// 业务逻辑
		} finally {
			threadLocal.set(null);
		}
	}
}
 

 

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics