java中的强引用
略就是普通的new对象
java中的软引用
使用SoftReference创建一个软引用对象,
当java的内存不足时,垃圾回收器会干掉软引用
软引用非常适合缓存使用
/**
* @version: JavaEE
* @description: java中的软引用
* @author: Mr.xzx
* @create: 2020-11-03 18:16
* @version:1.0
**/
public class SoftReferenceTest {
public static void main(String[] args) {
SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
System.out.println(m.get());
System.gc();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(m.get());
//再分配一个数组,heap将装不下,这时候系统会回收垃圾,先回收一次,如果不够,会把软引用干掉
byte[] b = new byte[1024 * 1024 * 15];
System.out.println(m.get());
}
}
java中的弱引用
垃圾回收器看到弱引用就会干掉弱引用
/**
* @version: JavaEE
* @description: java中的弱引用
* @author: Mr.xzx
* @create: 2020-11-03 18:43
* @version:1.0
**/
public class WeakReferenceTest {
public static void main(String[] args) {
WeakReference<M> m = new WeakReference<>(new M());
System.out.println(m.get());
System.gc();
System.out.println(m.get());
}
}
java中的虚引用
无论什么时候都get()不到该对象的引用
一个虚引用对象,要被回收时,垃圾回收器,会将它扔进一个队列(引用队列)中,如果引用队列中有该对象了,那么直接将这个虚引用对象直接回收
虚引用最大的作用是管理直接内存(堆外内存),实现零拷贝
public class PhantomReferenceTest {
private static final List<Object> list = new LinkedList<>();
private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();
public static void main(String[] args) {
PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);
System.out.println(phantomReference.get());
}
}
java中软引用的体现
ThreadLocal的讲解
public class ThreadLocalTest {
static ThreadLocal<M> tl = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tl.get());
}).start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tl.set(new M());
//tl.remove();如果tl不使用了,要调用remove方法,不然会存在内存泄漏(oom:内存溢出)
}).start();
}
}
threadLocal创建一个线程容器, 1号线程等待2秒,2号线程1秒就向容器中添加了一个M对象,但是1号线程2秒后依然无法get()到为null
所谓向ThreadLocal中set值,就是向当前线程Thread中的(父类成员变量)threadlocals的map中设置键值对,键是ThreadLocal本身,值是对象M();形成一个键值对Entry
这个键值对entry是继承了WeakReference弱引用
面试会问:线程池慎用ThreadLocal, 当我拿出一个线程,在他的map中添加了一些ThreadLocal的键值对,使用结束后也没有进行remove方法,那么我下次在拿到这个线程时,当中还会存在之前遗留的老的值,会出现值错乱等