(二) 详解JVM四种常见引用:强引用、软引用、弱引用、虚引用,一种不建议引用:终结器引用及JVM垃圾回收算法

本文详细介绍了Java中垃圾回收的基本原理,包括可达性分析算法及其如何判断对象是否可被回收。此外还深入探讨了不同类型的引用,如强引用、软引用、弱引用、虚引用和终结器引用的特点与应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

垃圾回收

可达性分析算法

由 Java 确定的一些根对象 (GC Root)可访问的对象将不会被垃圾回收,若是不可访问(不可达)则作为垃圾对象进行回收。

注:List intList = new arrayList<>(),new 出来的部分,即等于号后面的部分位于堆内,等号前的部分为堆内对象的引用,位于活动栈帧内。


四种常见引用及一种不建议使用引用

在这里插入图片描述

1、 强引用

直接被 GC Root 对象引用的对象,除非所有则 GC Root 对象对该对象的引用全部断开,否则不会被垃圾回收。

2、软引用(可配合引用队列使用)

发生内存回收时,发现内存不足,则有被 GC Root 对象软引用的对象可能被垃圾回收。

应用:若很大量的资源同时进行强引用,则内存空间很容易溢出

eg: List 集合内存储了大量的图片资源,每一个元素都将占用 > 4M 的内存,如何解决内存溢出的问题

由于 List 集合生命周期较长,故全部强引用将会大量的占用内存,容易造成内存溢出。

// 软引用的实例
public static void soft() {
	// List --> SoftReference --> byte[]
    // 软引用版List
	List<SoftReference<byte[]>> list = new ArrayList<>();
	for(int i = 0; i < 5; i++){
		SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB] );
		System.out.println(ref.get());
		list.add(ref);
		System.out.println(list.size());
	}
	System.out.print1n( "循环结束: " + list.size());
	for (SoftReference<byte[]> ref : list) {
		System.out.println(ref.get());
    }
}

运行结果:在这里插入图片描述

具体步骤:

  • 前两次 for 循环正常加入到 List<SoftReference<byte[]>> 集合内,内存较为不足。
  • 第三次 for 循环,产生一次 Minor GC(简单理解为清除新生代),但内存仍然很紧张。
  • 第四次 for 循环,加入 List 集合后,产生一次 Full GC 清理了大量的内存,代价就是将前4个元素直接清除。
  • 第五次 for 循环,将元素加入到 List 集合后,完成整个过程,最终 List 集合内只有最后一次循环加入的元素。

将内存设置为20M 软引用版本的代码没有发生内存溢出的问题,但代价就是 List 集合内仅能保存最后一次循环加入的元素,其余四个元素将被垃圾回收。


3、弱引用(可配合引用队列使用)

发生内存回收时,则有被 GC Root 对象弱引用的对象被垃圾回收。


4、虚引用(必须 配合引用队列使用)

发生内存回收时,ByteBuffer 所占用的内存被垃圾回收,但由 ByteBuffer 产生的直接内存将无法被回收,虚引用对象将记录直接内存的地址,并进入引用队列,在虚引用对象(Cleaner)中的Unsafe.freeMemory() 方法将直接内存回收掉。


5、终结器引用 - 不推荐(必须 配合引用队列使用)

所有的对象都继承自 Object 类,Object 类有一个 finallize() 方法 (终结方法),**若某个对象重写了 finallize() 方法并且没有强引用进行引用的话将可以被当做垃圾进行回收。**将重写了终结方法的对象进行垃圾回收时,首先 JVM 将为这个对象创建一个终结器引用,在调用终结方法时将终结器引用放入引用队列,此时该对象还没有被垃圾回收,在一个优先级很低的线程(finallizeHandler线程)发现引用队列中存在终结器引用时将调用待回收对象的 finallize() 方法,至此将在下一次垃圾回收时将该对象垃圾回收,这个过程优先级很低,可能导致长时间没有回收该内存,故终结器引用不建议使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值