JVM是如何判断内存是否存活

JVM有两种算法来判断对象是否存活,分别是引用计数法和可达性分析算法

引用计数法 :给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。

循环引用会导致对象无法被回收,最终会导致内存泄漏及内存溢出

可达性分析算法 : 这个算法的基本思想就是通过一系列的称为 "GC Roots" 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。

但是,并不是说当进行完可达性分析算法后,即可证明某对象可以被GC。对象是否存活,需要两次标记:

1.第一次标记通过可达性分析算法。如果没有GC Roots相连接的引用链,那么将第一次标记

2.如果对象的finalize()方法被覆盖并且没有执行过,则放在F-Queue队列中等待执行(不一定会执行),如果一段时间后该队列的finalize()方法被执行且和GC Roots关联,则移出"即将回收"集合。如果仍然没有关联,则进行第二次标记,才会对该对象进行回收

哪些内容可以作为GC roots

GC roots是作为可达性分析算法的起点的。要实现语义正确的可达性分析,就必须要能完整枚举出所有的GC Roots,否则就可能会漏扫描应该存活的对象,导致GC错误回收了这些被漏扫的活对象。那么,所谓"GC Roots",就是一组必须活跃的引用。

那么,有哪些引用是一定活跃的呢?看下下面这些是不是都符合这个条件:

Class - 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。

Thread - 活着的线程

Stack Local - Java方法的local变量或参数

JNI Local - JNI方法的local变量或参数

JNI Global - 全局JNI引用

Monitor Used - 被同步锁(synchronized)持有的对象

Held by JVM - 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此需要去确定哪些是属于"JVM持有"的了。

以上,比如系统类加载器加载的对象、活着的线程、方法中的本地变量、被synchronized锁定的对象这些,都是符合活跃的引用这个条件的!

GC roots缺点

STW时间长

可达性分析算法需要对程序进行全局分析,因此时间复杂度较高,可能需要很长的时间才能完成分析,并且整个过程都是STW的,所以对应用的整体性能有很大影响。这也使得可达性分析算法难以适用于大型程序的分析。所以一些常见的回收器都会使用一些优化技术来减少可达性分析的时间和开销,如增量标记、增量拷贝等。

内存消耗

可达性分析算法需要存储程序中所有的对象和它们之间的引用关系,这些信息需要占用大量的内存空间。对于大型程序,如果要进行完整的可达性分析,需要存储的对象数量和引用关系数量都非常大,可能会导致内存空间不足或者程序性能下降的问题。

相关推荐
酌沧5 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
wuminyu14 小时前
JVM规范学习总结-Java源码经过javac编译后产物
java·linux·c语言·jvm·c++
学到老活到老1 天前
类已经加载了,为什么静态代码还没执行?
java·jvm
学到老活到老1 天前
写了 new,就一定会在堆上分配对象吗?
java·jvm
笨笨饿1 天前
# 59_CSDN博客自动写流程文章
linux·jvm·stm32·单片机·嵌入式硬件·mcu·51单片机
tedcloud1232 天前
Docker Compose 部署 Memos:从安装到备份恢复
linux·开发语言·jvm·后端·docker·容器·rust
螺蛳粉 螺蛳粉2 天前
大数据第四篇:事故复盘:移走 HBase 里 27 个 hadoop-2.10.2 jar 后,HMaster 半小时后“自杀“了【jar 事故复盘】
jvm·hadoop·hbase·异常处理·大数据运维·踩坑记录·事故复盘
wuminyu2 天前
JVM规范学习总结-JVM规范基本概念
java·linux·c语言·jvm·c++
学到老活到老2 天前
方法执行完了,对象为什么还占着内存?
java·jvm
骑着蜗牛撵大象3272 天前
四种库收进一个SQL编辑器(下):跨库取数、方言对齐与四库巡检的落地拆解
jvm·数据库·sql·编辑器·数据迁移·跨库查询