弱引用
当被应用的强引用失去后,强引用关联的这个引用也就是虚引用相关的分配就会被回收
以ThreadLocal<T>为例
1.进行塞值
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}
2.一开始塞值肯定不存在就得走这个方法
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
3.里面这个firstKey就是Thread
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
4.构建个Entry
table[i] = new Entry(firstKey, firstValue);
5.Entry里面长这样,构造参数里面有个super(k)
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}

继续看顶层引用

默认这个queue是空,先不管它

一直到最底层

回头再来说,ThreadLocal的缺点,缺点有个啥来着,叫内存泄露,
ThreadLocal<String> threadLocal = new ThreadLocal<>();//直接new一个出来,这个是强引用
threadLocal.set("111");//塞值之后,把Thread和值放到里面的map里面去
一般情况下,threadLocal 消失后,塞值因为弱引用会被垃圾回收器回收。大并发情况下来不及回收,里面的map里面key引用的值来不及释放,没有及时被垃圾回收器回收,就造成了内存泄漏。
于是之前讲的InheritableThreadLocal就发挥作用了。
但是据我观察,jdk17之后
虽然弱引用机制没有改变,但是 JDK 17 中内存管理方面的改进间接增强了对ThreadLocal相关内存的控制。
例如,JDK 17 的垃圾回收器(如 ZGC 和 Shenandoah GC)的优化使得内存回收更加高效和及时。 在高并发场景下,这些优化后的垃圾回收器能够更频繁地检查内存中的弱引用对象。
当ThreadLocal对象作为弱引用被回收后,
内存管理系统可以更快地识别并处理对应的ThreadLocalMap中的Entry,减少了无效Entry(键已被回收但值还在)在内存中停留的时间
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/18632183

浙公网安备 33010602011771号