探索JVM的垃圾回收(堆内存)

Java 8+

-

 

序章

在 C/C++ 语言中,程序员自己分配内存、回收内存,不存在垃圾回收一说。

而在 Java 中,内存分配 绝大多数 是 JVM 的工作——栈内存、堆内存、永久代/元空间 等。ben发布于博客园

内存分配了就完了吗?不。JVM 运行时 的 内存不是无限的,受制于 程序员配置、系统内存上限,因此,在有限的内存中,还要进行 垃圾回收。

栈内存、永久代/元空间 不需要 垃圾回收,垃圾回收的重点在于——堆内存。(本句 存疑,毕竟,不是100%了解 Java Memory Model、垃圾回收 等,官文、源码没看过呢。)

 

近期看过几篇 JVM、垃圾回收的博文,特总结记录于此(总结了,才好提高嘛)。

ben发布于博客园

堆内存结构:(年轻代(Eden;Survivor(To;From;));老年代)

假设堆内存有50MB,默认情况下,其不同区分配的内存为:

修改配置调整(调优)后,比例应该就不同了。ben发布于博客园

 

HotSpot Virtual Machine Garbage Collection Tuning Guide

https://docs.oracle.com/en/java/javase/21/gctuning/preface.html

#可下载pdf

官方文档,介绍了 HotSpot VM (JVM 的 Oracle 实现) 的 垃圾回收调优,涉及 各种 垃圾回收器。

 

当然,Java 8 也有:ben发布于博客园

https://docs.oracle.com/javase/8/

不过,没有 PDF 下载了。

注,上面两个文档作者也是第一次打开,还没细看。

 

垃圾回收算法

》引用计数法:

存在循环引用问题。

英文:Reference Counting

 

》标记-清除算法 Mark-Sweep

引用:首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。
它是最基础的收集算法,后续的算法都是对其不足进行改进得到。
效率问题、空间问题(碎片)。

#参考资料2

英文:Mark-Sweep

 

》复制算法:

浪费内存。

不适合老年代。

英文:Copying Algorithm

 

》标记-整理算法 Mark-Compact

另名,标记-压缩算法

引用:是根据 老年代的特点 提出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,

而是 让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。

#参考资料2

英文:Mark-Compact

 

》分代收集算法 Generational Collection

引用:当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。

#参考资料2 文中还有 更多介绍。

引用:"分代收集算法基于对象的存活时间,将堆内存分为几代:

年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。

各代使用不同的收集算法。"

#参考资料6

英文:Generational Collection

 

说明,不同的垃圾回收算法 可能是 来自一篇篇 学术论文

 

垃圾回收器

》Serial:

单线程垃圾收集。ben发布于博客园

 

》ParNew:

Serial 收集器的多线程版本。

新生代采用标记-复制算法,老年代采用标记-整理算法。

英文:Par 是 Parallel 的缩写。

 

》Parallel Scavenge

引用:也是使用标记-复制算法的多线程收集器,它看上去几乎和 ParNew 都一样。

引用:Parallel Scavenge 收集器关注点是吞吐量(高效率的利用 CPU)。

引用:新生代采用标记-复制算法,老年代采用标记-整理算法。

引用:JDK1.8 默认使用的是 Parallel Scavenge + Parallel Old(下面)

如果指定了-XX:+UseParallelGC 参数,则默认指定了-XX:+UseParallelOldGC,可以使用-XX:-UseParallelOldGC 来禁用该功能。

 

英文:Scavenge(英 [ˈskævɪndʒ] vt.& vi.清除污物,打扫; (在废物中)寻觅; (动物)食腐肉)

 

》Serial Old:

Serial 收集器的老年代版本。

 

》Parallel Old

Parallel Scavenge 收集器的老年代版本。ben发布于博客园

 

》CMS:

引用:CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。

引用:HotSpot 虚拟机第一款真正意义上的【并发收集器】(不是 并行!)。

注意,出现了 Safepoint 概念

已废弃。

2020年3月:JDK14发布,剔除了CMS收集器。

引用:CMS 垃圾回收器在 Java 9 中已经被标记为过时(deprecated),并在 Java 14 中被移除。

 

》G1

引用:G1 (Garbage-First) 是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足 GC 停顿时间要求的同时,还具备高吞吐量性能特征。

引用:从 JDK9 开始,G1 垃圾收集器成为了默认的垃圾收集器

 

》ZGC

这款收集器的名字就叫作 Z Garbage Collector。ben发布于博客园

引用:

ZGC 在 Java11 中引入,处于试验阶段。
ZGC 在 Java15 已经可以正式使用了。

官网:

1、https://wiki.openjdk.org/display/zgc/Main

2、https://docs.oracle.com/en/java/javase/21/gctuning/z-garbage-collector.html

Quote:

The Z Garbage Collector (ZGC) is a scalable low latency garbage collector.

ZGC performs all expensive work concurrently, without stopping the execution of application threads for more than a millisecond.

It is suitable for applications which require low latency.

Pause times are independent of the heap size that is being used.

ZGC works well with heap sizes from a few hundred megabytes to 16TB.

 

》ShenandoahGC:

引用:Shenandoah GC 是一种低停顿的垃圾回收器,旨在解决传统垃圾回收器在大型堆上产生的停顿时间过长的问题。它是 OpenJDK 项目的一部分,并在 Java 12 中首次引入。

 

博文:Java 21 将放弃分代 Shenandoah GC

发布于 2023-06-17 23:22:06

https://cloud.tencent.com/developer/article/2296640

注,刚听说,就废弃了?ben发布于博客园

 

英文:Shenandoah([地名] [美国] 谢南多厄; [电影]烽火田园)

 

选择垃圾回收器的考虑因素

堆内存 大小。

停顿时间(Full GC 导致的 STW(Stop The World)):用户线程的停顿时间。

吞吐量:高效率的利用 CPU。ben发布于博客园

 

Minor GC vs Major GC vs Full GC

在 官文 HotSpot Virtual Machine Garbage Collection Tuning Guide 中可以搜索到 minor gc, major gc, full gc 等概念。

注,下面是在 Release 21(Java 21) 的 pdf文档中 检索。

搜索:minor

Quote: When the young generation fills up, it causes a minor collection in which only the young generation is collected; garbage in other generations isn't reclaimed.

Quote:  Eventually, the old generation fills up and must be collected, resulting in a major collection, in which the entire heap is collected.

搜索 full:ben发布于博客园

 

引用:

Minor GC 是 清理 新生代中的Eden区, Survivor区满时不会触发 ; Major GC 是 清理 老年代 ; Full GC 是 清理整个堆和方法区,包括 年轻代、老年代和方法区。

来自 参考资料#4

ben发布于博客园

注,官网文档 作者还未细看,信息或许不准确,请注意。

 

小结

Safepoint 的引入,实现了 并发垃圾收集。

Java 8 默认使用 Parallel Scavenge + Parallel Old。

Java 9+ 默认使用 G1(Garbage First)。

目前使用的是 Java 17,默认G1,也可以通过参数 -XX:+UseZGC 使用 ZGC。

打印GC运行 的参数:-XX:+PrintGCDetails

 

2024年,重点关注 G1、ZGC 两种,尤其是 默认的 G1。至于 比 Java 17 更高的版本,目前还没用过。

 

ben发布于博客园

---END---

 

引用了不少其它博文的语句,如有冒犯,请通知作者删除

水平非常有限,如有错漏,请不吝告知

谢谢。

 

本文链接:

https://www.cnblogs.com/luo630/p/18445951

 

参考资料

1、1.大白话带你认识 JVM
https://javaguide.cn/java/jvm/jvm-intro.html

2、JVM垃圾回收详解(重点)
https://javaguide.cn/java/jvm/jvm-garbage-collection.html

3、G1、ZGC、ShenandoahGC 高性能收集器深入剖析

Java全栈架构师的文章 - 知乎
https://zhuanlan.zhihu.com/p/624386102
发布于 2023-04-24 10:13

4、Minor GC、Major GC、Full GC的区别
发布于 2021-07-21 10:46:46

https://cloud.tencent.com/developer/article/1850327

5、官方文档:HotSpot Virtual Machine Garbage Collection Tuning Guide

6、深入理解Java的垃圾回收机制(GC)实现原理
2024-06-14
https://developer.aliyun.com/article/1537550

7、探索JVM垃圾回收算法:选择适合你应用的最佳GC策略
2024-08-16
https://developer.aliyun.com/article/1588394

8、

 

ben发布于博客园

ben发布于博客园

 

posted @ 2024-10-04 14:14  快乐的欧阳天美1114  阅读(38)  评论(0)    收藏  举报