强引用
-
对于强引用,是我们最常见的,比如直接创建一个对象:Object obj = new Object(); 那么ojb就是一个强引用。在当前栈帧有效的作用域内,是永远不会被回收的。
-
只要不是null,就不会被gc回收。
package com.heima.freemarker.reference;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SoftReferenceTest {
public static void main(String[] args) throws IOException {
// 强引用
byte[] list = new byte[1024];
// gc之前,list指向
System.out.println("before gc :" + list);
// gc
System.gc();
// gc之后,list指向
System.out.println("after gc :" + list);
}
}
软引用
- 软引用是指被SoftReference类实现的引用。它的特征是当前系统有足够的的内存的时候,它能够存活;当系统内存不足时,它会被gc回收。
- 使用场景:适合做缓存。
package com.heima.freemarker.reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
public class SoftReferenceTest {
public static void main(String[] args) {
// 软引用 占用1M内存
SoftReference<byte[]> str = new SoftReference<>(new byte[1024*1024]);
// list变量指向是强引用
List list = new ArrayList<>();
int i = 0;
while (true) {
// 死循环,每次消耗1M内存
list.add(new byte[1024 * 1024]);
// 查看软引用什么时候被回收
System.out.println("第" + ++i + "次时,软引用的内容为:" + str.get());
}
}
}
弱引用
- gc 会直接回收
package com.heima.freemarker.reference;
import java.io.IOException;
import java.lang.ref.WeakReference;
public class SoftReferenceTest {
public static void main(String[] args) throws IOException {
// 弱引用
WeakReference<byte[]> weakReference = new WeakReference<>(new byte[1024]);
// 垃圾回收前
System.out.println("before gc : " + weakReference.get());
// gc
System.gc();
// 垃圾回收后
System.out.println("after gc : " + weakReference.get());
}
}
虚引用
- 必须搭配队列使用。
- 使用场景:管理堆外内存
package com.heima.freemarker.reference;
import java.io.IOException;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class SoftReferenceTest {
public static void main(String[] args) throws IOException {
// 队列
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
// 虚引用
PhantomReference phantomReference = new PhantomReference(new byte[1024], referenceQueue);
// 垃圾回收前
System.out.println("before gc : " + phantomReference.get());
System.out.println("before gc : " + referenceQueue.poll());
// gc
System.gc();
// 垃圾回收后
System.out.println("after gc : " + phantomReference.get());
System.out.println("after gc : " + referenceQueue.poll());
}
}