问:JVM当中的垃圾分类怎么搞?

ops/2024/11/15 7:07:05/

在Java中,JVM(Java虚拟机)的垃圾识别与分类是自动内存管理的重要组成部分。这一过程主要通过垃圾收集器(Garbage Collector)实现,旨在识别和回收不再被程序引用的对象,以释放内存空间。

1. 垃圾识别与分类的基础

在Java中,所谓的“垃圾”是指没有任何引用指向的对象。这些对象虽然仍然占据着内存空间,但已经无法被程序访问和使用。为了识别和回收这些垃圾对象,JVM采用了多种算法和策略。

2. 垃圾识别算法

2.1 引用计数法

引用计数法是一种简单而直观的垃圾收集算法。其核心思想是通过在对象头中添加一个引用计数器,记录该对象被引用的次数。每当有一个新的引用指向该对象时,引用计数加一;当引用被删除或者超出作用范围时,引用计数减一。当引用计数为零时,表示该对象不再被引用,即可以被回收。

然而,引用计数法有一个明显的缺陷,即难以处理循环引用的情况。例如,两个对象互相引用,它们的引用计数永远不会变为零,即使它们已经不再被程序所使用。

示例代码

class ReferenceCountingObject {private int referenceCount = 0;public ReferenceCountingObject() {// 对象初始化时,引用计数为0}public void addReference() {referenceCount++;}public void removeReference() {referenceCount--;if (referenceCount == 0) {// 当引用计数为零时,可以进行垃圾回收操作System.out.println("对象被回收");}}
}public class ReferenceCountingExample {public static void main(String[] args) {// 创建两个对象ReferenceCountingObject obj1 = new ReferenceCountingObject();ReferenceCountingObject obj2 = new ReferenceCountingObject();// obj1引用计数加一obj1.addReference();// obj2引用计数加一obj2.addReference();// obj1引用计数减一obj1.removeReference();// obj1引用计数为零,可以进行垃圾回收// obj2引用计数仍为一}
}
2.2 可达性分析算法

可达性分析是Java虚拟机中垃圾收集的核心算法之一。它主要通过判断对象是否能够从一组称为"GC Roots"的根对象出发,通过引用链追踪,最终判断对象是否可达。GC Roots包括虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象以及本地方法栈中JNI(Java Native Interface)引用的对象。

可达性分析的过程如下:

  1. 初始标记阶段:STW(Stop-The-World),只标记GC根直接关联的对象,耗时极少。
  2. 并发标记阶段:由GC根依次向下标记所有关联的对象,可达为存活对象,不可达为可回收对象。
  3. 重新标记阶段:STW,标记新建的对象引用(GC收集器通过读写屏障+增量更新记录新建的引用对象)。
  4. 清除标记阶段:GC线程与用户线程并发清理被标记的垃圾对象。

可达性分析算法能够解决引用计数法无法处理的循环引用问题,因此成为当前主流虚拟机采用的垃圾收集算法。

3. 垃圾分类与回收算法

在识别出垃圾对象后,JVM需要采用合适的算法来回收这些对象所占用的内存空间。以下是几种常见的垃圾回收算法:

3.1 标记-清除算法

标记-清除算法是最基础的收集算法。它分为“标记”和“清除”两个阶段:

  1. 标记阶段:标记出所有存活的对象。
  2. 清除阶段:统一回收所有未被标记的对象。

然而,标记-清除算法存在两个明显的问题:

  1. 效率问题:如果需要标记的对象太多,效率不高。
  2. 空间问题:标记清除后会产生大量不连续的碎片。
3.2 复制算法

复制算法将堆内存分割成两块大小相同的区域,每次只使用其中一块进行对象分配。当这一块内存使用完后,就将还存活的对象复制到另一块区域,然后将已使用的内存空间一次清理掉。

复制算法的优点是不会产生内存碎片,但缺点是内存使用效率低,每次只能使用一半的内存空间。

3.3 标记-整理算法

标记-整理算法是对标记-清除算法的优化。它在标记阶段仍然标记所有存活的对象,但在清除阶段不是直接回收对象,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。

3.4 分代收集算法

分代收集算法是当前虚拟机普遍采用的垃圾收集算法。它将堆内存划分为新生代和老年代,根据对象的存活周期选择合适的垃圾收集算法。

  • 新生代:对象存活率低,通常使用复制算法进行回收。新生代被进一步划分为Eden区、From区和To区,默认内存分配比为8:1:1。
  • 老年代:对象存活率高,通常使用标记-清除算法或标记-整理算法进行回收。

4. 垃圾收集器

垃圾收集器是执行垃圾回收操作的组件。在Java中,有多种不同类型的垃圾收集器,包括串行收集器、并行收集器、CMS收集器和G1收集器等。这些收集器采用不同的算法和策略来实现垃圾回收。

4.1 串行收集器(Serial GC)

串行收集器是最基本的垃圾收集器,使用单线程进行垃圾回收。它在进行垃圾收集时,必须暂停其他所有的工作线程,直到收集结束。因此,串行收集器适用于单CPU环境或内存较小的应用。

4.2 并行收集器(Parallel GC)

并行收集器使用多线程进行垃圾回收,提高了回收效率。它同样需要暂停其他工作线程,但回收过程是多线程的,因此适用于多CPU环境或吞吐量要求较高的应用。

4.3 CMS收集器(Concurrent Mark-Sweep GC)

CMS收集器是一种以获取最短回收停顿时间为目标的收集器。它使用并发标记和并发清除的方式来实现垃圾回收,大大减少了停顿时间。然而,CMS收集器在垃圾回收过程中会占用一部分CPU资源,并且可能产生内存碎片。

4.4 G1收集器(Garbage-First GC)

G1收集器是一种面向服务器的垃圾收集器,旨在满足大内存、多处理器的环境下对停顿时间的要求。它将堆内存划分为多个区域(Region),每次只收集一部分区域的垃圾。G1收集器采用并发标记和并发清除的方式,同时结合了复制算法和标记-整理算法的优点,实现了高吞吐量和低停顿时间。

5. 总结

Java JVM中的垃圾识别与分类是自动内存管理的重要组成部分。通过可达性分析算法,JVM能够准确识别出垃圾对象;通过不同的垃圾回收算法和收集器,JVM能够高效地回收这些垃圾对象所占用的内存空间。对于Java开发人员而言,深入理解JVM的垃圾回收机制有助于优化应用性能、解决内存泄漏等问题。


http://www.ppmy.cn/ops/125972.html

相关文章

QT实现校园导航

导航是地图类项目实战中经常会遇到了。看上去貌似没头绪&#xff0c;其实是有模板遵循的。我们直接根据图看代码。 //MainWidget.h#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include "mapwidget.h" #include <QToolButton> #in…

JavaScript基础入门

目录 1. JavaScript简介 2. 基本语法 2.1 变量声明 2.2 数据类型 2.3 运算符 3. 控制结构 3.1 条件语句 3.2 循环语句 4. 函数 5. 数组与对象 5.1 数组 5.2 对象 6. DOM 操作 总结 JavaScript 是当今最流行的编程语言之一&#xff0c;它主要用于网页开发&#xf…

[Windows]文件搜索利器Everything(附zip)

前言 写代码过程中&#xff0c;老大突然发一条信息 老大&#xff1a;这周周报发一下。 我&#xff1a;好的。 然后我就 显示桌面打开-我的电脑找到E盘&#xff0c;找到周报文件夹寻找到所有周报中今天的周报复制发送 当我用上Everything之后 打开&#xff0c;输入周报copy发…

Could not find or load main class

今天接收项目&#xff0c;部署遇到的问题 解决方案 <properties><spring-boot.version>2.5.10</spring-boot.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></…

想要加密电脑文件?2024年企业常用的10款电脑加密软件排行榜

在2024年&#xff0c;随着网络安全威胁日益增多&#xff0c;企业对数据安全的需求越来越强烈。电脑文件加密已成为保护敏感信息免受未经授权访问的必备手段。企业为了确保数据安全&#xff0c;往往会选择专业的加密软件&#xff0c;帮助保护文件、文件夹、硬盘、甚至整个系统。…

Selenium打开外部应用程序的弹窗处理

问题 selenium自动化操作页面跳转到外部应用程序进行下载等操作&#xff0c;各种窗口处理方式无法解决 原因 该窗口属于浏览器窗口&#xff0c;与访问页面无关&#xff08;已经脱离页面操作层面&#xff09; 解决 selenium启动浏览器时&#xff0c;对浏览器进行相关窗口设…

CountUp.js 实现数字增长动画 Vue

效果&#xff1a; 官网介绍 1. 安装 npm install --save countup.js2. 基本使用 // template <span ref"number1Ref"></span>// script const number1Ref ref<HTMLElement>() onMounted(() > {new CountUp(number1Ref.value!, 9999999).sta…

mysql 备份文件导入问题

数据库导入一个sql文件的时候报错提示&#xff0c; ERROR 2006 (HY000) at line xx: MySQL server has gone away 需要设置max_allowed_packet的值&#xff1b; 查看当前的值&#xff1a; show VARIABLES like ‘%max_allowed_packet%’; 1、登录mysql mysql -uroot -p 2、设置…