JVM专题十:JVM中的垃圾回收机制

在JVM专题九:JVM分代知识点梳理中,我们主要介绍了JVM为什么采用分代算法,以及相关的概念,本篇我们将详细拆分各个算法。

垃圾回收的概念

垃圾回收(Garbage Collection,GC)确实是计算机编程中的一项重要技术,它自动化了内存管理过程,解决了手动内存管理(如在C或C++中)的复杂性和潜在错误。

在没有垃圾回收的情况下,程序员需要负责申请和释放内存,这不仅容易出错,还可能导致内存泄漏和其他资源管理问题。垃圾回收的引入,使得程序员可以更专注于程序逻辑,而不是内存细节。

正如你提到的,垃圾回收的概念最早可以追溯到1960年的Lisp语言,它是为了解决手动内存管理的繁琐和低效问题。Java语言设计时,将垃圾回收作为其核心特性之一,以简化内存管理并提高开发效率。

Java中的垃圾回收机制主要依赖于以下几个方面:

  • 自动内存管理:JVM自动追踪对象的引用情况,确定哪些对象不再被使用。
  • 垃圾收集算法:JVM使用不同的算法(如标记-清除、复制、标记-清除-整理等)来识别和回收垃圾对象。
  • 垃圾收集器:JVM提供了多种垃圾收集器,以适应不同的应用场景和性能需求。

Java的finalize方法类似于C++中的析构函数,提供了在对象被回收前执行清理操作的机会。但由于finalize的执行时机不确定,且可能影响垃圾回收的性能,因此通常不推荐依赖它来进行关键的资源回收。

总的来说,垃圾回收是现代编程语言的一个重要特性,它帮助开发者编写更安全、更高效的程序。Java作为一门高级语言,通过其垃圾回收机制,显著简化了内存管理的复杂性。

Java中的垃圾回收机制

自动内存管理

JVM自动追踪对象的引用情况,确定哪些对象不再被使用。这也是讨论垃圾回收的前提(只有知道谁是垃圾,才可以进行垃圾回收吗),常用的是引用计数法、可达性分析,垃圾判断

引用计数法

引用计数法是一种简单直接的垃圾回收算法。在这种方法中,每个对象维护一个计数器,用于记录有多少个引用指向该对象:

  1. 引用增加:当有引用指向一个对象时,对象的引用计数加一。
  2. 引用消失:当引用被清除时,对应的对象引用计数减一。
  3. 垃圾回收:当对象的引用计数为零时,表示没有任何引用指向该对象,该对象可以被垃圾回收。

优点

  • 垃圾对象可以很快被发现并回收。

缺点

  • 难以处理循环引用问题,即两个或多个对象相互引用,但对其他对象没有引用,按照引用计数法,这些对象的引用计数不为零,不会被回收。
  • 维护引用计数需要额外的开销,尤其是在大量对象和频繁更新引用的场景下。

可达性分析

可达性分析是JVM中更常用的垃圾回收算法,它基于一系列被称为GC Roots的根对象进行:

  1. GC Roots:包括Java方法栈中的局部变量静态变量本地方法栈中的引用等。
  2. 标记过程:从GC Roots开始,所有可达的对象都会被标记为存活,可达的是存活哈。
  3. 清除过程:未被标记的对象被认为是垃圾,可以被回收。

优点

  • 可以处理循环引用问题,因为可达性分析不依赖于引用计数,只要没有GC Roots可达的路径,对象就会被回收。
  • 适用于大规模的应用程序,因为它可以更精确地识别存活对象。

缺点

  • 需要暂停应用程序(Stop-the-World)来执行标记和清除过程,尤其是在Full GC时。
  • 标记和清除过程可能需要较长时间,尤其是在堆内存很大时。

STW

"Stop The World"(STW)是Java虚拟机(JVM)垃圾回收中的一个术语,指的是在执行垃圾回收时,JVM必须暂停应用程序的执行,以便在一致的状态进行内存的回收和整理。以下是STW的一些关键点:

  1. 全局一致性:STW确保了在垃圾回收期间,整个堆的状态是一致的,避免了并发执行时对内存状态的不一致性。

  2. 减少复杂性:通过暂停应用程序的执行,垃圾回收器可以简化其算法,因为不需要处理并发修改的问题。

  3. 性能影响:STW会导致应用程序的延迟增加,因为所有的应用线程都被挂起,直到垃圾回收完成。

  4. 优化目标:现代垃圾回收器的设计目标之一是减少STW的时间,以提高应用程序的响应性和吞吐量。

  5. 类型

    • Minor GC:通常很快,对新生代进行回收,STW时间较短。
    • Major GC 或 Full GC:涉及整个堆的回收,STW时间较长,对性能的影响也更大。
  6. 并发收集:一些垃圾回收器如CMS(Concurrent Mark-Sweep)和G1(Garbage-First),通过并发标记和清除阶段减少STW时间。

  7. 低延迟收集器:例如ZGC和Shenandoah,它们通过并发处理大部分GC阶段,极大地减少了STW事件。

  8. 调优:通过调整JVM参数和选择合适的垃圾回收器,可以优化STW事件,减少其对应用程序性能的影响。

  9. 监控:通过监控工具,如JConsole或VisualVM,可以观察STW事件和持续时间,以评估垃圾回收对性能的影响。

  10. 应用设计:应用程序设计时,应考虑到STW的影响,例如,避免在性能敏感的路径上进行长时间的GC。

STW是垃圾回收的一个挑战,现代JVM通过各种策略和算法来减少STW的影响,以提供更平滑的应用程序性能。

垃圾收集算法

标记-清除(Mark-Sweep)算法

标记-清除算法(Mark-Sweep)是一种基础的垃圾回收算法,如上图所示,它通过以下两个主要步骤来回收内存中的垃圾对象:

  1. 标记阶段:算法从根集合(GC Roots)开始,使用可达性分析法遍历所有可达对象,并将这些存活对象进行标记。

  2. 清除阶段:算法再次遍历内存区域,这次是为了识别那些未被标记的对象,即那些不再被引用的垃圾对象,并将它们清理掉,从而释放内存空间。

这种算法的优点在于逻辑简单,易于实现,但它也有明显的缺点,如上图回收后JVM内存图,会产生内存碎片问题:由于对象是逐个被清理的,这可能导致内存中出现许多小的空闲区域,也就是JVM内存碎片。内存碎片过多时,当程序需要分配较大的连续内存块时,可能无法找到足够的空间,即便总的空闲内存是足够的。这种情况可能导致提前触发新一轮的垃圾收集,影响程序性能。

复制(Copying)算法

复制算法(Copying)是在标记清除算法上演化而来的,用于解决标记清除算法的内存碎片问题。如上图所示:它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当其中一块使用完,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样就保证了内存的连续性,逻辑清晰,运行高效。

优势:

  1. 简单高效:复制算法避免了标记-清除算法中内存碎片的问题,实现简单,运行高效3。
  2. 高吞吐量:由于只处理存活对象,所以效率较高,尤其适合新生代对象存活率低的情况1。
  3. 内存分配快速:复制算法完成后,空闲内存是连续的,分配内存时只需移动堆顶指针,非常快速。

缺点:

  1. 内存利用率降低:由于需要两个内存区域,实际使用的内存只有一半。
  2. 对象复制成本:需要复制存活对象,这会带来一定的性能开销。上述缺点让人

标记-清除-整理(Mark-Sweep-Compact)算法

标记-清除-整理(Mark-Sweep-Compact)算法是一种垃圾回收算法,这个算法分为三个阶段:

  1. 标记(Mark):在这个阶段,垃圾回收器遍历所有可达对象,从根对象开始,标记所有可达的对象。这意味着垃圾回收器会识别出所有仍然在使用中的对象,以便在后续阶段不会被错误地回收。

  2. 清除(Sweep):一旦标记阶段完成,垃圾回收器将遍历堆内存,清除所有未被标记的对象。这个阶段可能会留下内存碎片,因为对象是逐个被清除的,而不是成块地清除。

  3. 整理(Compact):为了解决内存碎片问题,这个阶段会将所有存活的对象向堆的一端移动,使得它们紧密排列。然后,回收器可以简单地清理掉边界之外的所有内存。整理阶段完成后,堆内存中存活的对象是连续存放的,这有助于提高内存访问的局部性,从而提高性能。

优点:

  • 没有内存碎片:通过整理阶段,可以避免内存碎片的问题,使得内存使用更加高效。
  • 适用于老年代:由于老年代的对象存活率高,标记-清除-整理算法可以有效地管理这些对象。

缺点:

  • 效率问题:整理阶段可能需要移动大量的对象,这可能会导致相对较高的开销。
  • 暂停时间:标记和清除阶段可能会引起应用程序的暂停,尤其是在处理大量对象时。

在实际的JVM实现中,标记-清除-整理算法可能会有所变化,以适应不同的垃圾回收需求和优化性能。例如,某些实现可能会采用增量或并发的垃圾回收策略来减少应用程序的暂停时间。此外,现代JVM通常会结合使用多种垃圾回收算法,以适应不同内存区域的特点。

分代收集算法

分代收集算法(Generational Collection)是一个结合了多种基础垃圾回收算法的策略,它根据对象的生命周期特点,将堆内存划分为不同的区域,并对这些区域采用最适合的垃圾回收算法。

根据对象存活周期的不同会将内存划分为几块,一般是把 Java 堆分为新生代和老年代,新生代又可以分为Eden区和Survivor区,其中Survivor区又会分To与From区;这样就可以根据各个年代的特点采用最适当的收集算法,如上图所示。

在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用标记清理或者标记整理算法来进行回收。

Eden区
  • Eden区是新生代的一部分,大多数新创建的对象首先被分配到这里。
  • 据 IBM 公司之前的研究表明,有将近 98% 的对象是朝生夕死,正是由于对象的朝生夕死特性,Eden区经常需要进行Minor GC来回收垃圾对象。通过 Minor GC 之后,Eden 区中绝大部分对象会被回收,而那些无需回收的存活对象,将会进到 Survivor 的 From 区,如果 From 区不够,则直接进入 To 区。
Survivor区
  • Survivor区有两个,From和To,它们的作用是作为Eden区和Old区之间的缓冲。
  • 通过Minor GC,存活的对象从Eden区和From区复制到To区,这样可以减少直接晋升到老年代的对象数量,降低Major GC的频率。
  • 两个Survivor区的设计有助于避免内存碎片,并确保每次GC后都有一个Survivor区是空的,另一个是没有碎片的。

Survivor区的划分原因

  • 如果只有一个Survivor区,每次Minor GC后,存活对象和需要清除的对象都会混在一起,导致内存碎片问题。
  • 两个Survivor区可以在每次Minor GC后,将存活对象复制到空的Survivor区,从而保持内存的连续性。
Old区
  • 老年代占据了Java堆的大部分空间,主要用于存放长期存活的对象。
  • 由于老年代中对象的存活率高,通常使用标记-清除或标记-整理算法进行垃圾回收。

常用的垃圾回收器

上面介绍的两个小节自动内存管理和垃圾收集算法都是从理论上介绍了设计思路,具体的实现再落在具体的垃圾回收器上,下面罗列了目前主流的垃圾回收器。

Java虚拟机(JVM)提供了多种垃圾回收器,以适应不同的应用场景和性能要求。以下是一些常用的垃圾回收器及其特点:

  1. Serial GC:单线程,适合小内存和单核环境。
  2. ParNew GC:Serial的多线程版本,适合多核环境。
  3. Parallel Scavenge GC:追求吞吐量,适合后台处理。
  4. Serial Old GC:老年代单线程,使用标记-整理算法。
  5. Parallel Old GC:老年代多线程,与Parallel Scavenge配合。
  6. CMS GC:老年代并发收集,减少停顿时间,但可能产生内存碎片。
  7. G1 GC:堆分割为区域,追求低延迟和高吞吐量。
  8. ZGC:低延迟,几乎不牺牲吞吐量,适合大堆内存。
  9. Shenandoah:同样以低延迟为目标,由Red Hat开发。

每种垃圾回收器都有其特定的使用场景和优化目标。开发者可以根据应用程序的具体需求,选择合适的垃圾回收器来优化性能。随着Java技术的发展,新的垃圾回收器也在不断地被引入和优化。

小节

本章我们主要介绍了Java的垃圾机制,包括垃圾回收基本概念,重点介绍了垃圾回收机制中自动内存管理与垃圾收集算法。简短罗列了下常用见的垃圾回收器。下一篇我们见重点介绍各个垃圾回收器的特定、及适用的常见。 

最后还是提一个小问题:你们线上JVM的参数是什么,使用的是什么垃圾回收器呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/743401.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详解如何在分数限制下,选好专业还是选好学校?

系列文章目录 1、选好专业还是选好学校? 2、具体分段考虑 3、博主给学子的建议 文章目录 系列文章目录前言一、稳定军心二、鱼与熊掌真不可兼得吗?1.兴趣和职业规划2.专业实力3.就业前景4.个人发展 三、具体分段考虑1、高分段考生2、次高分段考生3、中…

住宅IP代理服务终极指南:增强安全性和可访问性

在当今的数字安装程序中,隐私和可访问性对于企业和个人都至关重要。满足这些需求的一个强大工具是住宅 IP 代理服务。这些服务为用户提供住宅 IP 地址,这些地址是互联网产品 (ISP) 计算房主的真实 IP。在本综合指南中,我们将探讨住宅 IP 代理…

手机照片压缩到20k以内免费,这几款心动软件快收好!

在数字化时代,手机拍照已成为我们记录生活的重要方式之一。然而,高清的照片也意味着占用着越来越多的手机存储空间。如果你正在为手机内存告急而烦恼,那么这几款手机照片压缩神器或许能成为你的救星!它们不仅可以将照片轻松压缩至…

docker-compose部署Flink及Dinky

docker-compose部署Flink及Dinky 服务器环境:centos7 1. 配置hosts vim /etc/hostsx.x.x.x jobmanager x.x.x.x taskmanager x.x.x.x dinky-mysql2. 文件目录结构 . ├── conf │ ├── JobManager │ │ ├── flink-conf.yaml │ │ ├── log…

高考英语3500词

DAY1 DAY2 DAY3 DAY4 DAY5 DAY6 DAY7 DAY8 DAY9 DAY10 DAY11 DAY12 DAY13 DAY14 DAY15 DAY16 DAY17 DAY18 DAY19 DAY20 DAY21 DAY22 DAY23 DAY24 DAY25 DAY26 DAY27 DAY28 DAY29 DAY30 DAY31 DAY32 DAY33 DAY34 DAY35 DAY36 DAY37 DAY38 DAY39 DAY40

这份AI绘画攻略赶紧码住!超适合小白入门的PS AI插件来啦!

有没有小伙伴对AI绘画很感兴趣,但是看到国外的mj和sd总觉得入门困难!别担心,米兔挖到一款超级绝的国产PS AI插件!适合新手学习,米兔这里还有一份专为小白准备的AI绘画攻略,让你的创意不再受限! …

解决vs2022scanf报错问题

vs2022scanf报错问题 大家下完vs2022之后,开心的写下一段简单的代码: #include <stdio.h> #include <stdlib.h>int main() {int a;scanf("%d", &a);printf("%d", a);return 0; } vs2022会毫不犹豫的报错,下面是报错信息: 翻译过来就是v…

打造智慧矿山:整体架构设计与实践探索

随着信息技术的不断发展&#xff0c;智慧矿山作为矿业领域的创新模式&#xff0c;正日益受到关注。在智慧矿山中&#xff0c;先进的传感器、大数据分析、人工智能等技术被广泛应用&#xff0c;以提高矿山生产效率、降低成本&#xff0c;并确保安全环保。本文将深入探讨智慧矿山…

云计算【第一阶段(20)】磁盘管理与文件系统 服务器硬件及RAID配置实战(三)

一、服务器硬件详解 cpu 主板 内存 硬盘 网卡 电源 raid卡 风扇 远程管理卡 1.1、硬盘尺寸 目前生产环境中主流的两种类型硬盘 3.5寸 和2.5寸硬盘 2.5寸硬盘可以通过使用硬盘托架后适用于3.5寸硬盘的服务器 但是3.5寸没法转换成2.5寸 二、RAID阵列详解 独立硬盘冗余阵…

七天速通javaSE:第三天 程序控制结构:顺序、选择、循环

文章目录 前言一、Scanner类1. hasNext()和hasNextLine()2.next()和nextLine()3. Scanner的其他用法 二、顺序结构三、选择结构1. if单选择结构2. if-else双选择结构3. if-else if多选择结构4. switch选择结构 四、循环结构1. while循环2.do while循环3. for循环&#xff08;常…

Linux系统学习——指令四

Linux系统学习——指令四 Linux 系统学习——指令四查看文件MD5校验和fuser 指令基本语法常用选项访问类型使用示例 系统信息 Linux 系统学习——指令四 查看文件MD5校验和 在Linux中&#xff0c;你可以使用 md5sum 命令来查看一个文件的MD5校验和。以下是具体的操作方法&…

超细毛搭配超宽设计,一款更呵护牙龈的牙刷

牙龈敏感的时候&#xff0c;刷牙特别难受&#xff0c;最近试了试惠百施&#xff08;EBISU&#xff09;65孔宽头软毛牙刷&#xff0c;感觉它的口腔护理体验很不错。这款牙刷的设计独特&#xff0c;采用宽头设计&#xff0c;一次就能刷两排牙齿&#xff0c;极大地提高了清洁效率。…

ServBay[中文] 下一代Web开发环境

ServBay是一个集成式、图形化的本地化Web开发环境。开发者通过ServBay几分钟就能部署一个本地化的开发环境。解决了Web开发者&#xff08;比如PHP、Nodejs&#xff09;、测试工程师、小型团队安装和维护开发测试环境的问题&#xff0c;同时可以快速的进行环境的升级以及维护。S…

解决msvcp120.dll问题的详细步骤,分析msvcp120.dll文件

msvcp120.dll文件是Microsoft Visual C Redistributable Package for Visual Studio 2013中的一个组件。如果提示你丢失该文件&#xff0c;通常意味着程序试图调用一个未在你电脑上安装的Visual C版本。下面是解决此问题的详细步骤。 msvcp120.dll丢失的解决方法 方法 1&#…

报餐小程序可以运用在饭堂的哪方面

随着科技的快速发展&#xff0c;智能化、信息化的管理方式逐渐渗透到我们日常生活的方方面面。在饭堂管理中&#xff0c;报餐小程序的应用为传统的餐饮管理方式带来了革命性的变革。本文将探讨报餐小程序在饭堂管理中的应用及其带来的优势。 一、报餐小程序的基本功能 报餐小程…

轮播图的制作大全

例如该样式: 1.Vue的方法(可实现自动轮播和左右按钮和下方原点按钮轮播) <div id="app"><div class="a" ref="b" @mouseenter="MouseFun(c)" @mouseleave="MouseFun(d)">//1.图片显示盒子<div class=&qu…

python-17-零基础自学python-

学习内容&#xff1a;《python编程&#xff1a;从入门到实践》第二版 知识点&#xff1a; 类、子类、继承、调用函数 练习内容&#xff1a; 练习9-6&#xff1a;冰激凌小店 冰激凌小店是一种特殊的餐馆。编写一个名为IceCreamStand的类&#xff0c;让它继承为完成练习9-1或…

JAVA每日作业day6.25

ok了家人们今天我们学习了&#xff0c;接口这个知识&#xff0c;我们闲话少叙&#xff0c;一起看看吧。 一&#xff0c;接口 1.1 接口概述 接口是功能的集合。接口的内部主要就是定义方法&#xff0c;包含常量&#xff0c;抽象方法&#xff08;JDK 7及以前&#xff09;&#…