JVM工作原理与实战(二十三):堆的垃圾回收-引用计数法和可达性分析法

简介: JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了判断堆上的对象是否可以回收的方法(引用计数法、可达性分析法)、查看垃圾回收日志等内容。

一、判断堆上的对象是否可以回收

在垃圾回收过程中,首要任务是判断哪些对象可以安全地回收。常见的判断方法主要有两种:引用计数法可达性分析法

1.引用计数法

引用计数法是一种直观且简单的垃圾回收策略。每个对象都持有一个引用计数器,当一个对象被引用时,其计数器加1;当引用被解除时,计数器减1。当计数器归0时,对象即被认为是可以回收的。

image.gif

引用计数法的优点在于其实现简单,对于某些特定场景(如C++中的智能指针)非常适用。然而,它也存在一些明显的缺点:

  • 每次引用或取消引用都需要更新计数器,这可能对系统性能产生影响。尤其是在对象引用频繁增减的情况下,这可能导致大量的更新操作,从而影响程序的运行效率。
  • 引用计数法无法处理循环引用的情况。例如,当对象A引用对象B,同时对象B也引用对象A时,即使这两个对象之间没有其他外部引用,它们的引用计数也不会归0,从而导致无法正常回收,造成内存泄漏。

2.可达性分析算法

相比之下,可达性分析算法更为复杂,但它能够解决循环引用问题。在可达性分析中,所有对象被分为两类:垃圾回收的根对象(GC Root)和普通对象。这些根对象通常是程序中可以直接访问的对象。算法通过追踪从根对象到目标对象的引用链,来判断一个对象是否可达。如果一个对象从任何根对象都无法达到,那么这个对象就被认为是不可达的,可以被安全地回收。

案例:

在图中,A对象引用了B对象,B对象又引用了C和D对象,从而形成了一个引用链。可达性分析算法的核心思想在于,如果一个对象无法从垃圾回收的根对象(GC Root)可达,那么这个对象就可以被安全地回收。反之,如果一个对象可以从某个GC Root对象可达,那么这个对象就被认为是活动的,不可被回收。

image.gif

在Java中,就采用了可达性分析算法来判定对象是否可以回收。所有的根对象都存在于线程的栈中或者其他一些固定区域(例如JDK中的强引用、软引用、弱引用、虚引用)。如果一个对象被根对象直接或间接引用,那么这个对象就被认为是活动的、不可被回收的;反之,如果一个对象没有任何根对象引用它,那么这个对象就可以被垃圾回收。

可达性分析算法的主要优点是它可以处理复杂的引用关系和避免循环引用的问题。然而,它也有一些缺点:

  • 可达性分析算法需要追踪和记录所有的引用关系,这可能会增加内存和CPU的使用。
  • 如果一个程序在运行过程中改变了引用关系(例如在Java中的null指针异常),这可能会影响到垃圾回收的结果。
  • 对于一些动态生成的对象或者短生命周期的对象,可达性分析可能无法有效地判定其是否可以回收。

GC Root对象:

在垃圾回收过程中,GC Root对象是指垃圾回收的起始点。这些对象是可达的,并且通过引用关系可以访问到堆上的其他对象。常见的GC Root对象包括:

  • 线程Thread对象:每个线程在Java虚拟机中都有一个对应的Thread对象,这些对象引用线程栈帧中的方法参数、局部变量等,为垃圾回收提供了可达性路径。
  • 系统类加载器加载的java.lang.Class对象:系统类加载器加载的java.lang.Class对象,这些对象引用类中的静态变量。
  • 监视器对象:当一个线程执行同步代码块或同步方法时,会创建一个监视器对象来保存同步锁的信息。
  • 本地方法调用时使用的全局对象:在使用本地方法(native method)时,Java虚拟机可能会创建一些全局对象。

二、查看垃圾回收日志

要获取垃圾回收的详细信息,可以使用-verbose:gc参数。该参数提供了关于垃圾回收操作的详细日志输出。

-verbose:gc

image.gif

通过使用此参数,可以获取有关垃圾回收的详细信息,包括每次垃圾回收的类型、回收前和回收后的内存使用情况等,这些信息对于分析和优化垃圾回收性能非常有用。

image.gif


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了判断堆上的对象是否可以回收的方法(引用计数法、可达性分析法)、查看垃圾回收日志等内容,希望对大家有所帮助。

相关文章
|
7月前
|
Oracle Java 关系型数据库
JVM深入原理(一+二):JVM概述和JVM功能
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行。
194 0
|
7月前
|
Arthas 存储 Java
JVM深入原理(三+四):JVM组成和JVM字节码文件
目录3. JVM组成3.1. 组成-运行时数据区3.2. 组成-类加载器3.3. 组成-执行引擎3.4. 组成-本地接口4. JVM字节码文件4.1. 字节码文件-组成4.1.1. 组成-基础信息4.1.1.1. 基础信息-魔数4.1.1.2. 基础信息-主副版本号4.1.2. 组成-常量池4.1.3. 组成-方法4.1.3.1. 方法-工作流程4.1.4. 组成-字段4.1.5. 组成-属性4.2. 字节码文件-查看工具4.2.1. javap4.2.2. jclasslib4.2.3. 阿里Arthas
128 0
|
7月前
|
存储 安全 Java
JVM深入原理(五):JVM组成和JVM字节码文件
类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析。
107 0
|
7月前
|
Arthas Java 测试技术
JVM深入原理(六)(一):JVM类加载器
目录6. JVM类加载器6.1. 类加载器-概述6.2. 类加载器-执行流程6.3. 类加载器-分类(JDK8)6.3.1. JVM底层实现的类加载器6.3.1.1. 启动类加载器6.3.2. Java代码实现类的加载器6.3.2.1. 扩展类加载器6.3.2.2. 应用程序类加载器6.4. 类加载器-Arthas查看类加载器
130 0
|
7月前
|
Java 关系型数据库 MySQL
JVM深入原理(六)(二):双亲委派机制
自定义类加载器打破双亲委派机制的方法:复写ClassLoader中的loadClass方法常见问题:要加载的类名如果是以java.开头,则会抛出安全性异常加载自定义的类都会有一个共同的父类Object,需要在代码中交由父类加载器去加载自定义类加载器不手动指定parent会默认指定应用类加载两个自定义类加载器加载同一个类会被认为是两个对象,只有相同的类加载器+想通的类限定名才会被认为是一个对象。
245 0
|
7月前
|
存储 安全 Java
JVM深入原理(七)(一):运行时数据区
栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存栈的组成:栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成栈帧:一个方法运行所需要的内存空间活动栈帧:一个线程中只能有一个活动栈帧栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行栈的执行流程:栈帧压入栈内执行方法执行完毕释放内存若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存。
134 0
|
7月前
|
存储 缓存 安全
JVM深入原理(七)(二):运行时数据区
堆的作用:存放对象的内存空间,它是空间最大的一块内存区域.栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间共享。堆的特点:线程共享:堆中的对象都需要考虑线程安全的问题垃圾回收:堆有垃圾回收机制,不再引用的对象就会被回收方法区的概述:方法区是存放基础信息的位置,线程共享,主要包括:类的元信息:保存了所有类的基本信息运行时常量池:保存了字节码文件中的常量池内容静态常量池:字节码文件通过编号查表的方式找到常量。
93 0
|
9月前
|
存储 算法 Java
G1原理—5.G1垃圾回收过程之Mixed GC
本文介绍了G1的Mixed GC垃圾回收过程,包括并发标记算法详解、三色标记法如何解决错标漏标问题、SATB如何解决错标漏标问题、Mixed GC的过程、选择CollectSet的算法
G1原理—5.G1垃圾回收过程之Mixed GC
|
9月前
|
存储 算法 Java
G1原理—6.G1垃圾回收过程之Full GC
本文详细探讨了G1垃圾回收器对Full GC(FGC)的优化处理,涵盖FGC的前置处理、整体流程及并行化改进。重点分析了传统FGC串行化的局限性以及G1通过Region分区和RSet机制实现并行标记的优势,包括任务窃取提升效率、跨分区压缩以生成空闲Region等技术细节。此外,文章还介绍了G1的新特性——字符串去重优化,通过判断char数组一致性减少重复字符串占用内存,从而提升内存使用效率。总结部分全面回顾了G1在FGC中的各项优化措施及其带来的性能改善。
G1原理—6.G1垃圾回收过程之Full GC
|
9月前
|
存储 算法 Java
G1原理—4.G1垃圾回收的过程之Young GC
本文详细解析了G1垃圾回收器中YGC(Young Generation Collection)的完整流程,包括并行与串行处理阶段。内容涵盖YGC相关参数设置、YGC与Mixed GC及FGC的关系、新生代垃圾回收的具体步骤(如标记存活对象、复制到Survivor区、动态调整Region数量等),以及并行阶段的多线程操作和串行阶段的关键任务(如处理软引用、整理卡表、重构RSet)。
G1原理—4.G1垃圾回收的过程之Young GC