吊打面试官:jvm探究之谈谈垃圾收集器

GC垃圾回收算法和垃圾收集器的关系?分别是什么?

GC算法(引用计数、复制、标记清除、标记整理)是内存回收的方法论,垃圾收集器就是算法的落地实 现;

因为目前为止还没有完美的收集器出现,更加没有万能的收集器,只是针对具体应用最合适的收集器, 进行分代收集;

4 种主要垃圾收集器

串行垃圾回收器(Serial)

它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。所以不适合服务器环 境。

并行垃圾回收器(Parallel)

多个垃圾收集线程并行工作,此时用户线程是暂停的,适用于科学计算、大数据处理首台处理等弱交互 场景。

并发垃圾回收器(CMS)

用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程,互联 公 司多用它,适用对响应时间有要求的场景。

G1垃圾回收器

G1垃圾回收器将堆内存分割成不同的区域然后并发的对其进行垃圾回收

谈谈垃圾收集器

怎么查看默认的垃圾收集器是哪个?

命令行输入: java -XX:+PrintCommandLineFlags -version

默认的垃圾收集器有哪些?

java 的 gc 回收的类型主要有几种:

UseSerialGC 、 UseParallelGC 、 UseConcMarkSweepGC 、 UseParNewGC 、 UseParallelOldGC 、 UseG1GC

垃圾收集器

垃圾收集器就来具体实现这些GC算法并实现内存回收。

不同厂商、不同版本的虚拟机实现差别很大,HotSpot 中包含的收集器如下图所示:

部分参数说明

DefNew => Default New Generation 【默认新一代】

Tenured => Old 【老年代】

ParNew => Parallel New Generation 【并行新一代】

PSYoungGen => Parallel Scavenge 【并行清除年轻区】

ParOldGen => Parallel Old Generation 【并行老年区】

Server / Client 模式分别是什么意思?

适用范围:只需要掌握 Server 模式即可,Client模式基本不会用

操作系统: 32位Window操作系统,不论硬件如何都默认使用 Client 的 JVM 模式。

32位其他操作系统,2G 内存同时有 2个 cpu以上用Server模式,低于该配置还是 Client 模式。

64位都是 Server 模式。

新生代

串行GC(Serial收集器)/ (Serial Copying)

一句话:一个单线程的收集器,在进行垃圾收集时候,必须暂停其他所有的工作线程直到它收集结束。

串行收集器是最古老,最稳定以及效率高的收集器,只使用一个线程去回收但其在进行垃圾收集过程中 可能会产生较长的停顿,Stop-The-World,虽然在手机垃圾过程中需要暂停所有其他的工作线程,但是 它简单高效,对于限定单个 CPU 环境来说,没有线程交互的开销可以获得最高的单线程垃圾收集效率, 因此Serial垃圾收集器依然是java虚拟机运行在 Client 模式下默认的新生代垃圾收集器。

对应 JVM 参数是: -XX:+UseSerialGC

开启后会使用:Serial(Young区用)+ Tenured(Old区用)的收集器组合

表示:新生代、老年代都会使用串行回收收集器,新生代使用复制算法,老年代使用标记-整理算法;

-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialGC

并行GC(ParNew)

一句话:使用多线程进行垃圾回收,在垃圾收集时,会 Stop-The-World 暂停其他所有的工作线程直到 它收集结束。

ParNew 收集器其实就是 Serial 收集器新生代的并行多线程版本,最常见的应用场景是配合老年代的 CMG GC 工作,其余的行为和Serial 收集器完全一样,ParNew 垃圾收集器在垃圾收集过程中同样也要 暂停所有其他的工作线程。它是很多 java 虚拟机运行在Server模式下新生代的默认垃圾收集器。

常用对应 JVM 参数 : -XX:+UseParNewGC 启用 ParNew 收集器,只影响新生代的收集,不影响老年 代。

开启上述参数后,会使用:ParNew(Young区用)+ Tenured 的收集器组合,新生代使用复制算法,老 年代采用标记-整理算法。

但是 ParNew + Tenured 这样的搭配, Java8已经不再被推荐;

说明:

-XX:ParallelGCThreads=N 限制线程数量,默认开启和CPU数目相同的线程数。也可以通过N开启自定义的线程数cpu>8 N = 5/8cpu<8 N = 实际个数-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseParNewGC

警告:

Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release

并行回收GC(Parallel)/(Parallel Scavenge)

Parallel Scavenge 收集器类似 ParNew ,也是一个新生代垃圾收集器,使用复制算法,也是一个并行的 多线程的垃圾收集器,俗称吞吐量优先收集器,一句话:串行收集器在新生代和老年代的并行化。

它重点关注的是:

可控制的吞吐量,比如程序运行100分钟,垃圾收集时间1分钟,吞吐量就是 99%。高吞吐量意味着高效 利用CPU的时间,它多用于在后台运算而不需要太多交互的任务。

自适应调节策略也是 ParallelScavenge 收集器与 ParNew 收集器的一个重要区别。虚拟机会根据当前系 统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间(-XX: MaxGCPauseMillis)或最大的吞吐量。

常用JVM 参数: -XX:+UseParallelGC-XX:+UseParallelOldGC (可互相激活)使用 ParallelScavenge 收集器。

开启该参数后:新生代使用复制算法,老年代使用标记-整理算法。

老年代

串行GC(Serial Old)/ (Serial MSC)

Serial Old 是 Serial 垃圾收集器老年代版本,它同样是单个单线程的收集器,使用标记-整理算法,这个 收集器也主要是运行在Client默认的 java虚拟机默认的年老代垃圾收集器。 在Server模式下,主要有两个用途(了解,版本已经到8及以后):

1、在 JDK 1.5 之前版本中与新生代的 Parallel Scavenge 收集器搭配使用。(Parallel Scavenge + Serial Old)

2、作为老年代版本中使用 CMS 收集器的后备垃圾收集方案。

并行GC(Parallel Old)/ (Parallel MSC)

Parallel Old 收集器是 Parallel Scavenge 的老年代版本,使用多线程的标记-整理算法,Parallel Old收 集器在 JDK1.6才开始提供。 在 JDK1.6 之前,新生代使用 Parallel Scavenge 收集器只能搭配老年代的 Serial Old 收集器,只能保证 新生代的吞吐量优先,无法保证整体的吞吐量。在 JDK 1.6 之前( Parallel Scavenge + Serial Old)。 Parallel Old 正是为了在年老代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高, JDK1.8后可以优先考虑新生代 Parallel Scavenge 和老年代 Parallel Old 收集器的搭配策略。在 JDK 1.8 及以后( Parallel Scavenge + Parallel Old)

JVM 常用参数:

-XX:+UseParallelOldGC 使用Parallel Old 收集器,设置该参数后,新生代 Parallel Scavenge + 老 年代 Parallel Old

并发标记清除GC(CMS)

CMS 收集器(Concurrent Mark Sweep:并发标记清除)是一种以获取最短回收停顿时间为目标的收集 器。

适合应用在互联 站或者 B/S 系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时 间最短。

CMS 非常适合堆内存大、CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器。

Concurrent Mark Sweep 并发标记清除,并发收集低停顿,并发指的是与用户线程一起执行。

开启该收集器的 JVM 参数: -XX:+UseConcMarkSweepGC ,开启该参数后会自动将 – XX:+UseParNewGC 打开;

开启该参数后,使用 ParNew(Young区用)+CMS(Old区用)+ Serial Old 的收集器组合,Serial Old 将作为CMS出错的后备收集器。

-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:UseConcMarkSweepGC

优点:并发收集停顿低

缺点:

1、并发执行,对CPU资源压力大

  • 由于并发进行,CMS在收集与应用线程会同时增加对内存的占用,也就是说,CMS必须要在老年代堆内存用 尽之前完成垃圾回收
  • 否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以 STW 的方式进行一次 GC,从而造成较 大停顿时间。
  • 2、采用的标记清除算法会导致大量碎片

  • 标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对 堆内存进行压缩。CMS也提供了参数
  • -XX:CMSFullGCsBeForeCompaction(默认0,即每次都进行内存整理) 来指定多少次 CMS 收集之 后,进行一次压缩的 Full GC.
  • GC 之如何选择垃圾收集器

    1、单CPU或小内存,单机程序

    -XX:+UseSerialGC

    2、多CPU,需要最大吞吐量,如后台计算型应用

    -XX:+UseParallelGC 或者 -XX:+UseParakkekOldGC

    3、多CPU,追求低停顿时间,需要快速响应如互联 应用

    -XX:+UseConcMarkSweepGC 或 -XX:+ParNewGC

    声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!

    (0)
    上一篇 2021年8月18日
    下一篇 2021年8月18日

    相关推荐