一、垃圾分类定义
垃圾分类是JVM垃圾分类中的第一步,这一步将堆中的对象分为存活对象和垃圾对象两类。
在垃圾分类阶段,JVM会从一组根对象开始,通过对象之间的引用关系,遍历所有的对象,并将所有存活的对象进行标记。在标记过程中,对象会被打上标记,以便在垃圾回收的后续阶段进行处理。被标记的对象就是存活对象,未被标记的对象则被视为垃圾对象,可以被垃圾回收器回收。
强引用、软引用、弱引用、虚引用等引用类型是用于控制垃圾回收的过程中对对象的生命周期的。它们的作用是告诉垃圾回收器哪些对象是可以被回收的,哪些对象是不可以被回收的。
二、 强引用、软引用、弱引用、虚引用在程序中的应用
1、强引用
//强引用
Object obj = new Object();
2、软应用
//软引用
SoftReference<Object> softRef = new SoftReference<>(obj);
//obj 不再具有强引用,仍有软引用
obj = null;
案例:
import java.lang.ref.SoftReference;
/**
* 软引用何时被收集
*/
public class SoftReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//100M的缓存数据
byte[] cacheData = new byte[100 * 1024 * 1024];
//将缓存数据用软引用持有
SoftReference<byte[]> cacheRef = new SoftReference<>(cacheData);
//将缓存数据的强引用去除
cacheData = null;
System.out.println("第一次GC前" + cacheData);
System.out.println("第一次GC前" + cacheRef.get());
//进行一次GC后查看对象的回收情况
System.gc();
//等待GC
Thread.sleep(500);
System.out.println("第一次GC后" + cacheData);
System.out.println("第一次GC后" + cacheRef.get());
//在分配一个120M的对象,看看缓存对象的回收情况
byte[] newData = new byte[120 * 1024 * 1024];
System.out.println("重新分配对象后," + cacheData);
System.out.println("重新分配对象后," + cacheRef.get());
}
}
得到的结果是:
第一次GC前null
第一次GC前[B@682a0b20
第一次GC后null
第一次GC后[B@682a0b20
重新分配对象后,null
重新分配对象后,null
分析:在代码中,cacheRef是软引用关联的对象,cacheData是去除强引用的对象。当我们第一次进行垃圾回收前后,内存足够,所以如图所示;重新分配对象后,内存空间不足,将软引用对象回收,所以输出了"重新分配对象后,null"
3、弱引用
//弱引用
WeakReference<Object> weakRef = new WeakReference<>(obj);
//obj 不再具有强引用,只有弱引用
obj = null;
4、虚引用
ReferenceQueue<Object> queue = new ReferenceQueue<>();
//虚引用
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);
//obj 不再具有强引用,只有虚引用
obj = null;
三、总结
- 强引用:保证对象不被垃圾回收,直到引用被显式地设置为
null
或超出作用域。 - 软引用:在内存不足时,垃圾回收器会回收软引用指向的对象,适合实现内存敏感的缓存。
- 弱引用:只要垃圾回收器发现了弱引用,就会回收其指向的对象,适合实现规范化映射和缓存元数据。
- 虚引用:主要用于跟踪对象的垃圾回收活动,不会影响对象的生命周期。