垃圾收集-判断对象的生死

简介: 垃圾收集-判断对象的生死


什么时候回收对象?当然是这个对象再也不会被用到的时候回收。所以要想解决 “什么时候回收?” 这个问题,我们要先能判断一个对象什么时候什么时候真正的 “死” 掉了,判断对象是否可用主要有以下两种方法。

判断对象是否可用的算法

引用计数算法

算法描述

给对象添加一个引用计数器,每有一个地方引用它,计数器加 1。引用失效时,计数器减 1。计数器值为 0 的对象不再可用。

缺点

很难解决循环引用的问题。即 objA.instance = objB; objB.instance = objA;,objA 和 objB 都不会再被访问后,它们仍然相互引用着对方,所以它们的引用计数器不为 0,将永远不能被判为不可用。

可达性分析算法(主流)

算法描述

从 “GC Root” 对象(根对象)作为起点开始向下搜索,走过的路径称为引用链(Reference Chain),从 “GC Root” 开始,不可达的对象被判为不可用。

Java 中可作为 “GC Root” 的对象:

  • 栈中(本地变量表中的 reference)
  • 虚拟机栈中,栈帧中的本地变量表引用的对象;
  • 本地方法栈中,JNI 引用的对象(native方法);
  • 方法区中
  • 类的静态属性引用的对象;
  • 常量引用的对象;

即便如此,一个对象也不是一旦被判为不可达,就立即死去的,宣告一个的死亡需要经过两次标记过程。

四种引用类型

JDK 1.2 后,Java 中才有了后 3 种引用的实现。

  • 强引用:Object obj = new Object() 这种,只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象。
  • 软引用: 用来引用还存在但非必须的对象。对于软引用对象,在 OOM 前,虚拟机会把这些对象列入回收范围中进行第二次回收,如果这次回收后,内存还是不够用,就 OOM。实现类:SoftReference
  • 弱引用: 被弱引用引用的对象只能生存到下一次垃圾收集前,一旦发生垃圾收集,被弱引用所引用的对象就会被清掉。实现类:WeakReference
  • 虚引用: 幽灵引用,对对象没有半毛钱影响,甚至不能用来取得一个对象的实例。它唯一的用途就是:当被一个虚引用引用的对象被回收时,系统会收到这个对象被回收了的通知。实现类:PhantomReference

宣告对象死亡的两次标记过程

当发现对象不可达后,该对象被第一次标记,并进行是否有必要执行 finalize() 方法的判断;

  • 不需要执行:对象没有覆盖 finalize() 方法,或者 finalize() 方法已被执行过(finalize() 只被执行一次);
  • 需要执行:将该对象放置在一个队列中,稍后由一个虚拟机自动创建的低优先级线程执行。

finalize() 方法是对象逃脱死亡的最后一次机会,不过虚拟机不保证等待 finalize() 方法执行结束,也就是说,虚拟机只触发 finalize() 方法的执行,如果这个方法要执行超久,那么虚拟机并不等待它执行结束,所以最好不要用这个方法。

finalize() 方法能做的,try-finally 都能做,所以忘了这个方法吧!

方法区的回收

永久代的 GC 主要回收:废弃常量无用的类

  • 废弃常量:例如一个字符串 “abc”,当没有任何引用指向 “abc” 时,它就是废弃常量了。
  • 无用的类:同时满足以下 3 个条件的类。
  • 该类的所有实例已被回收,Java 堆中不存在该类的任何实例;
  • 加载该类的 Classloader 已被回收;
  • 该类的 Class 对象没有被任何地方引用,即无法在任何地方通过反射访问该类的方法。
相关文章
|
小程序 Java 数据安全/隐私保护
基于微信小程序的音乐平台 毕业设计 JAVA+Vue+SpringBoot+MySQL
基于微信小程序的音乐平台 毕业设计 JAVA+Vue+SpringBoot+MySQL
294 1
|
安全 Linux PHP
轻松搭建Linux宝塔面板并实现公网访问Discuz论坛,让您的论坛更具吸引力
轻松搭建Linux宝塔面板并实现公网访问Discuz论坛,让您的论坛更具吸引力
|
中间件 API
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
这篇文章介绍了作者在使用Nextjs15进行项目开发时遇到的部署问题。在部署过程中,作者遇到了打包构建时的一系列报错,报错内容涉及动态代码评估在Edge运行时不被允许等问题。经过一天的尝试和调整,作者最终删除了lodash-es库,并将radash的部分源码复制到本地,解决了打包报错的问题。文章最后提供了项目的线上预览地址,并欢迎读者留言讨论更好的解决方案。
298 0
Next.js 实战 (八):使用 Lodash 打包构建产生的“坑”?
|
Java 监控 自然语言处理
一站式链路追踪:阿里云的端到端解决方案
端到端链路追踪是覆盖全部关联 IT 系统,能够完整记录用户行为在系统间调用路径与状态的最佳实践方案。而真正实现端到端链路追踪,需要解决三个难题:链路插桩、链路采集与加工、链路上下文透传。阿里云 ARMS 目前已支持全链路端到端追踪,快来查看转发吧~
61918 102
Pyqt5--属性动画-文本移动(Pyside6适用)
Pyqt5--属性动画-文本移动(Pyside6适用)
526 1
Pyqt5--属性动画-文本移动(Pyside6适用)
|
人工智能 自动驾驶 PyTorch
【人工智能】Transformers之Pipeline(五):深度估计(depth-estimation)
【人工智能】Transformers之Pipeline(五):深度估计(depth-estimation)
344 2
|
计算机视觉
【已解决】cv2.imread读取中文名称图片报错或者无法保存中文名图片:使用cv2.imdecode与cv2.imencode解决
【已解决】cv2.imread读取中文名称图片报错或者无法保存中文名图片:使用cv2.imdecode与cv2.imencode解决
|
存储 Unix C#
【.NET Core】深入理解IO之Path
【.NET Core】深入理解IO之Path
303 2
|
人工智能 运维 Kubernetes
带你读《云原生架构白皮书2022新版》——云原生技术中台 CNStack 产品家族
带你读《云原生架构白皮书2022新版》——云原生技术中台 CNStack 产品家族
614 70
|
分布式计算 DataWorks Java
MaxCompute操作报错合集之DataWorks中udf开发完后,报错了,如何解决
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。