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的,所以对应用的整体性能有很大影响。这也使得可达性分析算法难以适用于大型程序的分析。所以一些常见的回收器都会使用一些优化技术来减少可达性分析的时间和开销,如增量标记、增量拷贝等。

内存消耗

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

相关推荐
H.莓飛10 小时前
【C++】内存管理
linux·开发语言·jvm·c++·visual studio
10mAh10 小时前
【SQL】NOT IN 遇到 NULL 为什么返回空集?三值逻辑与反关联实战
jvm·数据库·sql
wuminyu12 小时前
stackChunkOop内部结构与GC屏障的配合工作原理剖析
java·linux·c语言·jvm·c++
老三牛擦1 天前
订单履约流程
jvm
青春逝如流水2 天前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
colinu2 天前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++
wuminyu2 天前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
DongQiShanRen2 天前
玄龙(上):TICK 主循环——意识心跳怎么跳
linux·jvm·数据库·人工智能·数据挖掘·rust
leisoo80972 天前
融资融券数据怎么查两融指标含义与杠杆观察方法 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
leisoo80972 天前
股票筹码分布怎么用获利比例成本区间与集中度实战 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·开源