JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。

大厂面试真题:GC 算法有多少种?各自优缺点是什么?年轻代和年老代选择哪种算法最优?

     首先回顾一个图,也就是.class文件的类加载过程,以及线程执行、java内存模型图。看过系列1、2、3三篇文章的同学,大脑先回顾一遍类加器类型、双亲委派机制、如何打破双亲委派机制、GC内存划分、各个区域存放什么数据、以及给你一段代码要知道具体如何执行,对象什么时候被回收的逻辑。有道是,磨刀不误砍柴工,温故而知新,巩固基础,修炼JVM调优进阶核心技术。


       然后堆内存空间区域划分,在上一篇文章系列2以及说过,具体如下图,再回顾一下,年轻代分了Eden区和S1、S2区,堆内存里除了年轻代,其他都是老年代空间。

     今天重点讲的就是堆内存的GC算法以及GC处理过程,一步步来,希望本系列(预计100篇)结题的时候,有缘刷到的同学都有所收获,都能做JVM线上问题排查和JVM调优。


一、年轻代GC 复制算法

      我们知道,当一个新对象要存到堆内存里,这里暂且不说大对象,对象都是优先放到年轻代的Eden区。那随着时间推移,如下图Eden区满了,怎么办?答案:那肯定是要发生YGC,也就是Minor GC。

YGC采用的是什么GC算法?

答: 复制算法。

那为什么选这个算法?

答:稍等,后文解答。

复制算法核心逻辑是:将GC发现有GC Roots也就是还存活的对象,统一挪到S区。


1.1 复制算法的三个阶段

1、标记阶段

从GC Roots集合开始,标记还存活被引用的对象;

2、转移阶段

即把存活对象复制到新的内存地址上。

3、重定位阶段

因为复制转移导致对象的地址发生了变化,在这个重定位阶段,要把所有指向对象的旧地址的指针调整为新内存地址。

1.2 举例具体YGC过程

1、最开始,所有新对象在Eden区,发生YGC后,将存活的对象放到S1区;

2、再发生YGC,就把Eden区和S1区的存活对象,放到S2区。新对象继续放Eden区;

3、再发生YGC,就把Eden区和S2的存活对象,放到S1区。新对象继续放Eden区;

2和3反复。

如下图,当YGC结束后,Eden区就变干净,S区的1或2会存放存活对象,而另一个S区也是干净的。


1.3 复制算法有什么优点?

实现简单,另外由于没有标记和清除过程,执行效率高(毕竟存活的对象总是很少),而且复制对象到S区,使得内存空间总是连续的,没有空间碎片,那内存碎片问题就解决了。另外通过Eden+S1+S2三个区,而且是8:1:1的空间比例,内存利用率也很高,高达90%,仅仅浪费10%,相比传统复制算法只分两个区(5:5占比划分),内存利用率大幅提升。

1.4 复制算法的缺点是什么?

唯一缺点,就是没有100%利用内存,会有一些浪费。目前年轻代的这种分区复制算法,以及非常优秀,仅浪费10%左右内存,这个参数可以根据实际情况进行JVM调优。

看完复制算法的优缺点,这回就知道年轻代为什么适合用复制算法了:核心是年轻代每次GC后存活的对象很少,用复制算法效率高。

1.4 年轻代对应的垃圾回收器有哪些?

年轻代对应的GC回收器有Serial 垃圾回收器、ParNew垃圾回收器。


二、老年代GC 标记-整理算法

    老年代的GC,也就是FullGC,那FullGC什么时候会触发呢?

    一般就是当YGC之后发现存活对象很多,S区放不下了,或者触发某些规则,必须放老年代那边。这时候会去检查老年代还有多少空闲空间,如果发现老年代那边的空闲空间放不下,那就要先发生一个FullGC腾空间。

     老年代FullGC主流采用的是标记-整理算法,核心原理大概是这样:

 把老年代里的存活对象标记处理,然后清理那些已经可以GC回收的对象。最后把相关存活对象归集整理放在一篇连续内存区域,避免有内存碎片。

      老年代的这个标记回收算法,是非常慢的,效率比年轻代回收慢一个数量级。

      老年代对应的GC回收器有Serial Old垃圾回收器、CMS垃圾回收器。

2.1 标记-整理算法过程具体说说

1、标记(Marking)

与其他算法标记类型,从根对象开始,标记出所有存活的对象。

2、整理(Compacting)

在标记清除可以被回收的对象后,将所有存活的对象向一片连续内存移动,这样可以消除内存碎片提高老年代的内存使用率。

3、更新引用

在整理过程中,由于对象位置有挪动修改,所以对象内部的引用也需要进行同步更新,以指向移动后的对象地址。

  发现这个过程和复制算法是差不多的,核心差异在整理那,不过那细讲也要写一篇来说,后续出文再讲。

2.2 标记整理算法的优缺点是什么?

优点:解决了标记-清理算法存在的内存碎片问题,使得内存空间更加紧凑,提高了内存利用率。

缺点:由于需要对存活对象进行移动,这会导致一定的性能开销,降低了GC效率。

2.3 老年代为什么不用复制算法?

     老年代的标记整理算法竟然效率这么低,为啥不该用复制算法呢?

      这是因为老年代的对象存活率会较高,每次FGC,很可能有超过50%对象还会存活。如果存活的对象多,那复制操作的效率也一样会变低。同样,有一个的标记清除算法也可以应用在老年代中,但是它效率和标记整理算法差不多,也不高,且在内存回收后容易产生大量内存碎片。因此标记整理算法(Mark-Compact)算法,是老年代较优的选择。

本文仅重点介绍分区复制算法、还有标记整理算法,除了这两个还有标记-清除算法(Mark-Sweep)、分代收集算法(Generational Collection)。这里不再赘述。


推荐阅读:

1、JVM进阶调优系列(3)堆内存的对象什么时候被回收?

2、JVM进阶调优系列(2)字节面试:JVM内存区域怎么划分,分别有什么用?

3、JVM进阶调优系列(1)类加载器原理一文讲透

4、JAVA并发编程系列(13)Future、FutureTask异步小王子

相关文章
|
16天前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
38 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
16天前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
31 3
|
24天前
|
存储 算法 Java
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
42 2
|
25天前
|
缓存 算法 Java
GC垃圾收集算法
这篇文章详细讨论了垃圾收集(GC)的几种算法,包括引用计数、可达性分析、标记-清除、标记-复制和标记-整理算法,并介绍了这些算法的优缺点和适用场景。
20 0
GC垃圾收集算法
|
24天前
|
存储 Java PHP
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
46 0
|
7天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
25天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真
### 算法简介 1. **算法运行效果图预览**:展示算法效果,完整程序运行后无水印。 2. **算法运行软件版本**:Matlab 2017b。 3. **部分核心程序**:完整版代码包含中文注释及操作步骤视频。 4. **算法理论概述**: - **MSER**:用于检测显著区域,提取图像中稳定区域,适用于光照变化下的交通标志检测。 - **HOG特征提取**:通过计算图像小区域的梯度直方图捕捉局部纹理信息,用于物体检测。 - **SVM**:寻找最大化间隔的超平面以分类样本。 整个算法流程图见下图。
|
4天前
|
人工智能 算法 数据安全/隐私保护
基于遗传优化的SVD水印嵌入提取算法matlab仿真
该算法基于遗传优化的SVD水印嵌入与提取技术,通过遗传算法优化水印嵌入参数,提高水印的鲁棒性和隐蔽性。在MATLAB2022a环境下测试,展示了优化前后的性能对比及不同干扰下的水印提取效果。核心程序实现了SVD分解、遗传算法流程及其参数优化,有效提升了水印技术的应用价值。
|
5天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化CNN-LSTM网络的数据分类识别算法matlab仿真
本项目展示了基于贝叶斯优化(BO)的CNN-LSTM网络在数据分类中的应用。通过MATLAB 2022a实现,优化前后效果对比明显。核心代码附带中文注释和操作视频,涵盖BO、CNN、LSTM理论,特别是BO优化CNN-LSTM网络的batchsize和学习率,显著提升模型性能。
|
10天前
|
存储
基于遗传算法的智能天线最佳阵列因子计算matlab仿真
本课题探讨基于遗传算法优化智能天线阵列因子,以提升无线通信系统性能,包括信号质量、干扰抑制及定位精度。通过MATLAB2022a实现的核心程序,展示了遗传算法在寻找最优阵列因子上的应用,显著改善了天线接收功率。