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发布于博客园