ThreadLocal内存泄漏
2019-01-30 本文已影响0人
手打丸子
JAVA8中,ThreadLocal的实现是每一个Thread对象维护一个ThreadLocalMap,每个Entry都是一个弱引用,而一个对象只有弱引用时会被回收,线程结束后,这个变量就没有强引用了,自然会被回收;
但是,在使用线程池的时候,由于线程池内线程是复用的,所以会导致内存泄漏;
测试代码:
public class ThreadTest {
private static ThreadLocal<User> userResource = new ThreadLocal<User>();
public static class User{}
public static void main(String[] args) throws InterruptedException {
Set<Integer> hashRecord= ConcurrentHashMap.newKeySet();
ThreadPoolExecutor executor=new ThreadPoolExecutor(10,10,100, TimeUnit.MINUTES,new LinkedBlockingQueue());
CountDownLatch countDownLatch=new CountDownLatch(100);
for(int i=0;i<100;i++) {
executor.submit(() -> {
try {
if (null == ThreadTest.userResource.get()) {
ThreadTest.userResource.set(new User());
}
System.out.println(ThreadTest.userResource.get());
hashRecord.add(ThreadTest.userResource.get().hashCode());
}finally {
//ThreadTest.userResource.remove();
countDownLatch.countDown();
}
});
}
countDownLatch.await();
System.out.println(hashRecord.size());
}
}
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@233f585c
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@731f7d35
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@24e0614d
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@68abf112
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@e71df55
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@3cc49e81
10
可以看到一共只创建了10个User对象
放开//ThreadTest.userResource.remove();
可以看到:
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@5d63e601
com.dianping.orderdish.queue.shop.bas.service.ThreadTest$User@2f9891a9
100
一共创建了100个User对象