强软弱虚
1.普通引用,对象引用(被回收时,会调用finalize 方法)
2.软引用
a.设置 -Xmx20M 设置堆内存最大为20M
b.SoftReference<byte[]> m = new SoftReference<>(new byte[1024*1024])
c.此时创建一个强引用,1024*1024*20
d.此时m对象会被回收
3.弱引用
a.WeakReference,只要一执行GC就回收了,能get到, 一次性消费。
4.虚引用NIO,用于提高效率,实现zero copy)
a.PhantomReference,get不到, 管理堆外内存。
b. jvm中的堆内存会有一块内存,指向堆外内存(
c.过程:虚引用被回收时,会被放入到一个队列中,GC发现queue中有新值了,则会处理堆外内存(属于操作系统的内存)
ThreadLocal
概念:线程本地内存。(仅仅和当前线程相关,其他线程无法获取)
举例:spring 的@Transactional 注解,必须保证 两个内部方法是同一个连接。
分析过程:Thread 对象,中有一个属性 ThreadLocal.ThreadLocalMap,当执ThreadLocal 对象的get方法时,实际上是将ThreadLocal 对象的hascode作为key 对象值作为value,存放在ThreadLocal.ThreadLocalMap属性中。其中key为weak引用,是为了保证 ThreadLocal.ThreadLocalMap属性不指向ThreadLocal 对象时,可以直接被回收。
源码如下:(其实就是一个map key为当前线程)
//Thread 类,ThreadLocalMap 属性
ThreadLocal.ThreadLocalMap threadLocals = null;
//Thread的静态内部类,(用于存放ThreadLocal变量)
static class ThreadLocalMap
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
//如果为空,则创建一个ThreadLocalMap,并设置给 Thread 的threadLocals 属性
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
//ThreadLocalMap 的Entry 使用的是WeakReference 引用
//key 是 ThreadLocal对象引用(每个线程都是)当 每个线程都有自己的ThreadLocalMap
static class Entry extends WeakReference<ThreadLocal<?>>
为什么Entry 的key 使用的是弱引用?
1.当thread tl 指向 为空时, ThreadLocal对象 需要被回收,如果ThreadLocalMap 中的key为强引用的话,这不会被回收
2.ThreadLocalMap被回收时,ThreadLocalMap 的key为null,如何回收ThreadLocalMap 中的记录呢,调用 remove方法
必须remove,才能删除 ThreadLocalMap中的值。
image.png
网友评论