带你整理面试过程中关于 JVM 中分代收集算法分区收集算法和垃圾收集器的相关知识

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你整理面试过程中关于 JVM 中分代收集算法分区收集算法和垃圾收集器的相关知识相关的知识,希望对你有一定的参考价值。

文章目录

一、分代收集算法和分区收集算法

1. 分代收集算法

JVM根据对象存活周期的不同将内存划分为新生代、老年代和永久代,并根据各年代的特点分别采用不同的GC算法。

  • 新生代与复制算法
    新生代主要存储短生命周期的对象,因此在垃圾回收的标记阶段会标记大量已死亡的对象及少量存活的对象,因此只需选用复制算法将少量存活的对象复制到内存的另一端并清理原区域的内存即可。
  • 老年代与标记整理算法
    老年代主要存放长生命周期的对象和大对象,可回收的对象一般较少,因此JVM采用标记整理算法进行垃圾回收,直接释放死亡状态的对象所占用的内存空间即可。

2. 分区收集算法

分区算法将整个堆空间划分为连续的大小不同的小区域,对每个小区域都单独进行内存使用和垃圾回收,这样做的好处是可以根据每个小区域内存的大小灵活使用和释放内存

分区收集算法可以根据系统可接受的停顿时间,每次都快速回收若干个小区域的内存,以缩短垃圾回收时系统停顿的时间,最后以多次并行累加的方式逐步完成整个内存区域的垃圾回收。

如果垃圾回收机制一次回收整个堆内存,则需要更长的系统停顿时间,长时间的系统停顿将影响系统运行的稳定性。

二、垃圾收集器

Java堆内存分为新生代和老年代:新生代主要存储短生命周期的对象,适合使用复制算法进行垃圾回收;

老年代主要存储长生命周期的对象,适合使用标记整理算法进行垃圾回收。

因此,JVM针对新生代和老年代分别提供了多种不同的垃圾收集器,

针对新生代提供的垃圾收集器有Serial、ParNew、Parallel Scavenge,针对老年代提供的垃圾收集器有Serial Old、Parallel Old、CMS,还有针对不同区域的G1分区收集算法

垃圾收集器的详细内容学习:一篇文章带你深入了解Java虚拟机中的经典垃圾收集器

并发垃圾收集器:

指用户线程可以和垃圾收集器同时执行(不一定并行,可能会交替执行),即用户程序执行的同时,垃圾收集器运行在另一个CPU上
比如:CMS,G1
优点:良好的响应速度能提升用户体验,所以非常适合需要和用户交互的程序

并行垃圾收集器:

指多条垃圾收集线程并行工作,但此时用户线程处于等待状态
比如:Parallel Scavenge,Parallel Old
优点:高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务

1. Serial垃圾收集器:单线程,复制算法

Serial垃圾收集器基于复制算法实现,它是一个单线程收集器,在它正在进行垃圾收集时,必须暂停其他所有工作线程,直到垃圾收集结束


Serial垃圾收集器采用了复制算法,简单、高效,对于单CPU运行环境来说,没有线程交互开销,可以获得最高的单线程垃圾收集效率,因此Serial垃圾收集器是Java虚拟机运行在Client模式下的新生代的默认垃圾收集器。

2. ParNew垃圾收集器:多线程,复制算法

ParNew垃圾收集器是Serial垃圾收集器的多线程实现,同样采用了复制算法,它采用多线程模式工作,除此之外和Serial收集器几乎一样

ParNew垃圾收集器在垃圾收集过程中会暂停所有其他工作线程,是Java虚拟机运行在Server模式下的新生代的默认垃圾收集器。


ParNew垃圾收集器默认开启与CPU同等数量的线程进行垃圾回收,在Java应用启动时可通过-XX:ParallelGCThreads参数调节ParNew垃圾收集器的工作线程数。

3. Parallel Scavenge垃圾收集器:多线程,复制算法

Parallel Scavenge收集器是为提高新生代垃圾收集效率而设计的垃圾收集器,基于多线程复制算法实现,在系统吞吐量上有很大的优化,可以更高效地利用CPU尽快完成垃圾回收任务

Parallel Scavenge通过自适应调节策略提高系统吞吐量,提供了三个参数用于调节、控制垃圾回收的停顿时间及吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数,控制吞吐量大小的-XX:GCTimeRatio参数和控制自适应调节策略开启与否的UseAdaptiveSizePolicy参数。

所谓吞吐量就是处理器用于运行用户代码的时间与处理器总消耗时间的比值,即:

如果虚拟机完成某个任务,用户代码加上垃圾收集总共耗费了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

停顿时间越短就越适合需要与用户交互或需要保证服务响应质量的程序,良好的响应速度能提升用户体验;而高吞吐量则可以最高效率地利用处理器资源,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的分析任务

4. Serial Old垃圾收集器:单线程,标记整理算法

Serial Old垃圾收集器是Serial垃圾收集器的老年代实现,同Serial一样采用单线程执行,不同的是,Serial Old针对老年代长生命周期的特点基于标记整理算法实现

Serial Old垃圾收集器是JVM运行在Client模式下的老年代的默认垃圾收集器。

新生代的Serial垃圾收集器和老年代的Serial Old垃圾收集器可搭配使用,分别针对JVM的新生代和老年代进行垃圾回收,其垃圾收集过程如图1-15所示。在新生代采用Serial垃圾收集器基于复制算法进行垃圾回收,未被其回收的对象在老年代被Serial Old垃圾收集器基于标记整理算法进行垃圾回收。

5. Parallel Old垃圾收集器:多线程,标记整理算法

Parallel Old垃圾收集器采用多线程并发进行垃圾回收,它根据老年代长生命周期的特点,基于多线程的标记整理算法实现。

Parallel Old垃圾收集器在设计上优先考虑系统吞吐量,其次考虑停顿时间等因素,如果系统对吞吐量的要求较高,则可以优先考虑新生代的ParallelScavenge垃圾收集器和老年代的Parallel Old垃圾收集器的配合使用

注重的是吞吐量

新生代的Parallel Scavenge垃圾收集器和老年代的Parallel Old垃圾收集器的搭配运行过程如图1-16所示。新生代基于Parallel Scavenge垃圾收集器的复制算法进行垃圾回收,老年代基于Parallel Old垃圾收集器的标记整理算法进行垃圾回收。

这也是 JDK1.8 默认使用的垃圾收集器

6. CMS垃圾收集器

CMS(Concurrent Mark Sweep)垃圾收集器是为老年代设计的垃圾收集器,其主要目的是达到最短的垃圾回收停顿时间,基于线程的标记清除算法实现,以便在多线程并发环境下以最短的垃圾收集停顿时间提高系统的稳定性

CMS 保证的是响应速度

CMS的工作机制相对复杂,垃圾回收过程包含如下4个步骤:

  • 初始标记:只标记和GC Roots直接关联的对象,速度很快,需要暂停所有工作线程。
  • 并发标记:和用户线程一起工作,执行GC Roots跟踪标记过程,不需要暂停工作线程。
  • 重新标记:在并发标记过程中用户线程继续运行,导致在垃圾回收过程中部分对象的状态发生变化,为了确保这部分对象的状态正确性,需要对其重新标记并暂停工作线程。
  • 并发清除:和用户线程一起工作,执行清除GC Roots不可达对象的任务,不需要暂停工作线程。

CMS垃圾收集器在和用户线程一起工作时(并发标记和并发清除)不需要暂停用户线程,有效缩短了垃圾回收时系统的停顿时间,同时由于CMS垃圾收集器和用户线程一起工作,因此其并行度和效率也有很大提升。

7. G1垃圾收集器

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

G1(Garbage First)垃圾收集器为了避免全区域垃圾收集引起的系统停顿,将堆内存划分为大小固定的几个独立区域,独立使用这些区域的内存资源并且跟踪这些区域的垃圾收集进度,同时在后台维护一个优先级列表,在垃圾回收过程中根据系统允许的最长垃圾收集时间,优先回收垃圾最多的区域

G1 的1意思就是优先回收分区后垃圾较多的区域

G1垃圾收集器通过内存区域独立划分使用和根据不同优先级回收各区域垃圾的机制,确保了G1垃圾收集器在有限时间内获得最高的垃圾收集效率。

相对于CMS收集器,G1垃圾收集器两个突出的改进。

  • 基于标记整理算法,不产生内存碎片。
  • 可以精确地控制停顿时间,在不牺牲吞吐量的前提下实现短停顿垃圾回收。

分为:初始标记、并发标记、最终标记、筛选回收

缺点
由于是分区域管理,所以适用于大内存应用

由于需要通过记忆表记录新生代和老年代之间的引用关系,所需需要占用大量的内存,成本较高,负载较高,影响效率。

三、内存分配与回收策略

对象的内存分配,从概念上讲,应该都是在堆上分配

在经典分代的设计下,新生对象通常会分配在新生代中,少数情况下(例如对象大小超过一定阈值)也可能会直接分配在老年代

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC

大对象就是指需要大量连续内存空间的Java对象,最典型的大对象便是那种很长的字符串,或者元素数量很庞大的数组,大对象直接进入老年代

长期存活的对象将进入老年代(为做到这点,虚拟机给每个对象定义了一个对象年龄(Age)计数器,存储在对象头中)

回收策略指的就是分代设计情况下的不同回收方式(青年代,老年代,永久代)

四、其他相关知识点学习

(1)JVM 默认的垃圾收集器

jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)
jdk1.9 默认垃圾收集器G1

(2)查看JVM的垃圾收集器

java -XX:+PrintCommandLineFlags -version 

以上是关于带你整理面试过程中关于 JVM 中分代收集算法分区收集算法和垃圾收集器的相关知识的主要内容,如果未能解决你的问题,请参考以下文章

带你整理面试过程中关于JVM 调优的相关知识

带你整理面试过程中关于JVM 的运行机制多线程和 JVM 的内存区域的相关知识点

带你整理面试过程中关于一致性Hash算法的相关知识点

46道面试题带你了解高级Java面试,在线面试指南

带你整理面试过程中关于锁升级的过程

带你整理面试过程中关于多线程的编程问题