当前位置:   article > 正文

ThreadLocal内存泄漏问题以及解决方案_threadlocal内存泄漏怎么解决

threadlocal内存泄漏怎么解决

首先了解下ThreadLocal的结构

Thread中有成员变量ThreadLocalMap,ThreadLocalMap的key是ThreadLocal,ThreadLocalMap的value是被弱引用WeakReference修饰的对象

源码代码如下:

 

这个ThreadLocalMap(threadLocals)其实是线程Thread中的一个变量

 

 

  看到这里其实就好理解了

为什么会发生内存泄漏?

Threadlocal里面使用了一个存在弱引用的ThreadLocalMap,key是ThreadLocal,而value的引用是一个弱引用。

当线程(Thread)被回收时候只有ThreadLocalMap的key(ThreadLocal)被回收,而ThreadLocalMap对应value(ThreadLocalMap.Entry)的由于被弱引用修饰不会被回收,所以回收后ThreadLocalMap的key就变成了null,但value中却还有值。由于只有创建的value的线程可以访问这些缓值,但创建的线程已经被回收掉了,而其他线程永远访问不到这值,这时候就产生了垃圾对象,从而造成内存泄漏

解决方法:

1.使用完毕后及时调用ThreadLocal.remove() 局部变量 中使用调用remove方法,本质就是找到Entry中key为null的数据然后清除)

2.把ThreadLocal设置为全局变量,使得它无法被GC回收(如果在 成员变量 中使用就将修饰符设置为public static,ThreadLocal不会被回收也就不会存在key为null的情况, 也就不会内存泄漏)

附:

(解释:Java中的静态变量不会被垃圾回收器回收。public static静态变量是与类相关联的,而不是与类的实例相关联的,它们存储在方法区中,而不是堆内存中。垃圾回收器只会回收堆内存中不再被引用的对象,而不会回收方法区中的对象。)
 

java中的全局变量是由public修饰的static成员变量,形如public static int ID;
java中的全局变量是放在静态方法区中的,所有的实例对象会共享同一份全局变量。所以一旦对某个类实例化后对其中的全局变量做出修改,那么其他的实例其中的全局变量值也相应的会被修改。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号