ThreadLocal提供线程局部变量。不加锁,每个线程独立获得线程共有的一份内存拷贝,不用加锁。
注意:内存泄露。
1、必须回收自定义ThreadLocal变量,尤其是在线程池场景下会被复用,如果不清理自定义ThreadLocal变量,变量值会累加。
可能会影响后续业务逻辑和造成内存泄露等问题。尤其在try-finally
ThreadLocal内有自己的实例副本,该副本只由当前线程自己使用。
Thread,ThreadLocal,ThreadLocalMap关系
Thread类中包含了ThreadLocal类,ThreadLocal类又有一个ThreadLocalMap静态内部类
通过
ThreadLocal的getMap()找到对应的ThreadLocals是一个ThreadLocalMap
当为threadLocal复制到时候,实际上是以当前threadLocal实例为key,值为value的Entry往这个threadLocalMap存放
ThreadLocalMap保存ThreadLocal对象的一个map。
ThreadLocalMap中存放的entry全是弱引用。
ThreadLocal内存泄露问题:
内存泄露:不再使用的内存,不被回收。
Java允许使用finalize()方法在垃圾收集器中将对象从内存中清除出去之前做到 必要清理工作。
1、强软弱虚
强:JVM开始垃圾回收,就算出现了OOM也不会对对象进行回收。最常见的强引用是把一个对象赋给引用变量,这个引用变量就是一个强引用。
当一个对象被强引用引用的时候,处于可达状态,它是不可能被垃圾回收的
造成内存泄露的主要原因
软:系统内存充足的时候,不会回收。
弱:对于弱引用对象,只要垃圾回收机制一运行,不管JVM内存是否充足,都会回收该对象。应用场景,避免每次都从硬盘中读取,放在内存中用软引用。
GC必定被回收
虚: 虚引用必须和引用队列联合使用(phantomreference)。
用来实现比finallize机制更灵活的回收。
GC必定被回收
当前key为空,弱引用,value但是还存在引用。造成内存泄露,value依然存在强引用。
必须要手动调用remove方法,才能将key为空的删掉。
总结: