【JVM垃圾回收】如何判断对象可以回收+四种引用类型

一、如何判断对象可以回收

1、引用计数法

​ 只要这个对象被其他变量所引用,就让对象的引用计数+1。如果引用了2次,就让计数变成2,如果不引用了,-1。

【注】循环引用的情况

如下图所示的循环引用。各自的引用计数均为1。虽然都不会再使用了,由于引用计数不是0,所以不能进行垃圾回收,引起内存泄漏。

在这里插入图片描述

2、可达性分析算法

首先确定根对象(根对象肯定不能当做垃圾回收的对象)

  • Java 虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象
  • 扫描堆中的对象,看是否能够沿着 GC Root 对象 为起点的引用链找到该对象,找不到,表示可以回收
  • 哪些对象可以作为 GC Root ?
    • 虚拟机栈中的局部变量表所引用的对象
    • 方法区中的类静态属性引用和常量引用对象
    • 本地方法栈中所引用的对象

【演示GC Root】

在这里插入图片描述

List1是一个引用,存在于活动栈帧里面,属于局部变量。

new ArrayList这一段是存储在堆里面的

在当前活动线程中,局部变量所引用的对象可以作为根对象

在这里插入图片描述

在这里插入图片描述

执行了list1=null这一句后, 现在已经没了ArrayList这个对象,live这个参数就会自动执行一次垃圾回收。

【注】

Jmap:查看堆内存的占用情况

在这里插入图片描述

Jamp-dump:将堆内存运行时的状态转储成一个文件

format:格式

b:二进制

live:表示会主动触发一次垃圾回收

file:表示抓取后的快照存放在哪个文件下

21384:进程编号

3、关于垃圾回收的四种引用

在这里插入图片描述

实线代表强引用,虚线代表其他的几种引用

(1)强引用

只有所有 GC Roots 对象都不通过【强引用】引用该对象,该对象才能被垃圾回收

(2)软引用
  • 【前提】:没有强引用引用当前的这个软引用对象

  • 仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次出发垃圾回收,回收软引用对象

  • 可以配合引用队列来释放软引用自身

    • 在创建这个软引用对象时,创建了一个引用队列,那么软引用所引用的对象被垃圾回收后,软引用自身就会进入引用队列
    • 若要释放软引用自身的内存空间,通过引用队列来找到并进行释放。

【演示软引用】

在这里插入图片描述

在这里插入图片描述

List对softReference是强引用,而softReference对于byte[ ]属于软引用

前面一种属于强引用,会导致内存溢出。

使用软引用的好处:当内存紧张时,首先会触发minor GC,小规模的进行垃圾回收,回收年轻代,在进行下一次操作,如果现在仍然内存紧张,并且触发miner GC后,仍然不会有改观,就会触发full GC,进行大规模的垃圾回收。

在这里插入图片描述

针对当前代码,就是前4个被软引用的对象都被垃圾回收了,只剩下第五个了

【演示软引用,配合引用队列】

当前为null的软引用本身可以进行清除,需要使用引用队列。

在这里插入图片描述

使用了垃圾回收后,软引用本身会进入引用队列。

要将这部分清楚,得到的结果就是没有null值的。

(3)弱引用
  • 仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象
  • 可以配合引用队列来释放弱引用自身

【演示弱引用】

在这里插入图片描述
在这里插入图片描述

进行到第10次时,直接调用了一次full GC,只剩下最后一个了。之前的和软引用类似。

(4)虚引用

必须配合引用队列使用,主要配合 ByteBuffer 使用。被引用对象回收时,会将虚引用入队,由 Reference Handler 线程调用虚引用相关方法释放直接内存

调用cleanner方法,根据直接内存的地址,调用unsafe对象的freeMemory方法

(5)终结器引用

无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队(被引用对象暂时没有被回收),再由 Finalizer 线程通过终结器引用找到被引用对象并调用它的 finalize方法,第二次 GC 时才能回收被引用对象

不推荐,考虑情况较多,效率比较低

学自黑马程序员,加上自己的理解和整理,侵删

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值