面试官:怎么做JDK8的垃圾收集器的调优(面试常问)

看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题。擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说:

在JDK8中有Serial收集器、Parallel收集器、CMS收集器、G1收集器这么几种收集器,需要根据实际硬件配置和业务需求进行选择调优。

如此浅显的回答,无法让面试官达到深入的要求,肯定不能满足面试官强烈的需求,果不其然面试官又追问到:如果是桌面应用,内存占用也就100MB,应该选择哪种垃圾收集器呢?我快速的回答:Serial收集器。看着面试官期待的眼神,我又详细解释到:

Serial收集器

Serial收集器是使用单线程处理所有的垃圾收集工作的,因为没有多线程的额外开销,相对来说也是比较有效的。所以,最适合单核CPU环境,因为本来也没办法利用多核。不过,当应用的使用的内存大小在100MB左右甚至更小的时候,在也适用于多核CPU的环境。

我一边说着,一边在纸上画了起来:

Client模式的JVM默认的垃圾收集器就是Serial收集器,或者可以使用JVM参数-XX:+UseSerialGC显式启用Serial收集器。

面试官又追问到:如果是要求高吞吐量的应用,使用较大内存并且有多核CPU,应该选择哪种垃圾收集器呢?我快速的回答:Parallel收集器。看着面试官期待的眼神,我又详细解释到:

Parallel收集器

Parallel收集器是类似于Serial收集器的分代收集器,主要区别是在垃圾回收的时候使用了多个线程进行加速垃圾的收集。所以,对于使用较大内存并且有多核CPU的环境更加适合。

我一边说着,一边在纸上画了起来:

Server模式的JVM默认的垃圾收集器就是Parallel收集器,也可以使用JVM参数-XX:+UseParallelGC启用。启用Parallel收集器后默认情况下,Minor垃圾收集(针对年轻代的垃圾收集)和Major垃圾收集(针对老年代的垃圾收集)都是并行执行的,可以进一步减少垃圾收集的开销。

Parallel收集器可以通过JVM参数指定最大垃圾收集暂停时间、吞吐量(用户代码运行时间/(用户代码运行时间+垃圾收集运行时间))和堆占用空间的目标值:

  • -XX:MaxGCPauseMillis:最大垃圾收集暂停时间,单位为毫秒,如:-XX:MaxGCPauseMillis=200,表示垃圾收集暂停时间最大为200毫秒。默认情况下,没有指定最大垃圾收集暂停时间。如果指定了暂停时间目标,则会调整堆大小与垃圾收集相关的其他参数,使垃圾收集的暂停时间短于指定值。这些调整可能导致降低应用的整体吞吐量,也有可能无法始终满足所指定的最大垃圾收集暂停时间目标。
  • -XX:GCTimeRatio:吞吐量大小,如:-XX:GCTimeRatio=19,表示将垃圾收集运行时间的目标设定为应用总运行时间(用户代码运行时间+垃圾收集运行时间)的1/(1+19),即5%。默认值为99,垃圾收集的目标时间占应用总运行时间的1/(1+99),即1%。
  • -Xmx:堆占用的最大占用空间,如:-Xmx1G,表示堆占用的最大占用空间为1GB。另外,Parallel收集器还有一个隐含的目标:只要满足其他目标的同时,把堆占用内存的大小最小化。

这三个目标是有优先级的:

  1. 高优先级:最大垃圾收集暂停时间
  2. 中优先级:吞吐量目标
  3. 低优先级:最小堆占用内存目标

Parallel收集器按照指定的目标对分代大小和底层进行自动调节,尽量达到指定的目标,但不保证百分之百能达到。

面试官又追问到:如果同样是使用较大内存并且有多核CPU,但是要求垃圾收集暂停时间要尽可能短的Web应用,应该选择哪种垃圾收集器呢?我稍微思考了一下,回答:CMS收集器。看着面试官期待的眼神,我又详细解释到:

CMS收集器

CMS(Concurrent Mark Sweep)收集器是为那些要求垃圾收集暂停时间尽可能短,并且可以和垃圾收集器共享CPU资源的应用设计的。具有相对较大的内存使用并有多核CPU的应用,往往会更适合CMS收集器的使用。可以使用JVM参数-XX:+UseConcMarkSweepGC启用CMS收集器,启用后同时作用于Minor垃圾收集(针对年轻代的垃圾收集)和Major垃圾收集(针对老年代的垃圾收集)。

CMS收集器尝试通过使用单独的垃圾收集器线程在执行用户线程的同时并跟踪可访问对象,来减少由于Major垃圾收集而导致的暂停时间。在每个Major垃圾收集周期中,CMS收集器会在收集开始时暂停所有用户线程一小段时间,然后在收集的中期再次暂停。第二个暂停往往是两个暂停中较长的一个,在两个暂停之间都使用多个线程并行做收集工作的。所以,CMS收集器的垃圾收集过程分为以下四个步骤:

  1. 初始标记(CMS initial mark):这个步骤会暂停所有用户线程,但耗时非常短,标记GC Root直接关联的对象。
  2. 并发标记(CMS concurrent mark):这个步骤耗时较长,但用户线程可同时运行,标记至GC Root有可达路径的对象。
  3. 重新标记(CMS remark):这个步骤会暂停所有用户线程,但耗时比较短。由于步骤2用户线程同步运行,所以要修正在步骤二中用户线程同步运行产生对象标记的变动。
  4. 并发清除(CMS concurrent sweep):这个步骤耗时较长,但用户线程可同时运行。

我一边说着,一边在纸上画了起来:

面试官继续追问到:如果堆中有超过50%的活跃对象,分配对象和对象升代的频率较高,垃圾收集停顿时间大于0.5秒,应该选择哪种垃圾收集器呢?我稍微思考了一下,回答:G1收集器。看着面试官期待的眼神,我又详细解释到:

G1收集器

G1(Garbage-First)收集器是一款主要面向服务端应用的垃圾收集器,适用于具有大内存的多核CPU的服务器。它尝试在高概率下同时满足较小的垃圾收集暂停时间和较高的吞吐量。所有堆相关的操作(如:全局标记)与用户线程同时运行,这样可以避免随着堆内存的大小的增加垃圾收集的停顿时间也跟着增加。

G1收集器是垃圾收集技术历史上里程碑的成果,它跳出了之前收集整个代垃圾的思维模式,开创了收集器面向局部收集的设计思路和基于Rigion的内存布局形式。在之后的JDK版本中,G1收集器正在逐渐成为了CMS收集器的替代者和继任者。

G1收集器虽然遵循分代收集的设计,但是整个堆的内存设计有显著的不同。整个堆被划分为一组大小相等的独立区域(Region),每个独立区域(Region)都有一个连续的虚拟内存范围,并且根据需要在逻辑被划分为年轻代的Eden区、Survivor区或者老年代。

我一边说着,一边在纸上画了起来:

通过JVM参数-XX:MaxGCPauseMillis来给G1收集器指定垃圾收集的目标停顿时间,默认是200毫秒。G1收集器会使用预测模型来估算停顿时间内可以收集多少个独立区域。在一次垃圾回收结束时,G1收集器会选择下次将要收集哪些独立区域。通常情况下,G1收集器通过选择年轻代独立区域的数量来控制垃圾收集的停顿时间。与其他垃圾收集器一样,可以通过参数指定年轻代的大小,但是这样做可能会影响G1收集器达到停顿时间目标的效果。除了停顿时间目标之外,还可以通过JVM参数-XX:GCPauseIntervalMillis指定停顿的间隔时长,默认是0。

听了我的回答后,面试官对我会心一笑,我仿佛还在她的眼神中看到了一丝倾慕。正所谓:金风玉露一相逢,便胜却人间无数,欲知后事如何,且听下回分解。

总结

到此这篇关于面试官:怎么做JDK8的垃圾收集器的调优(面试常问)的文章就介绍到这了,更多相关JDK8的垃圾收集器的调优内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JAVA垃圾收集器与内存分配策略详解

    引言 垃圾收集技术并不是Java语言首创的,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言.垃圾收集技术需要考虑的三个问题是: 1.哪些内存需要回收 2.什么时候回收 3.如何回收 java内存运行时区域的分布,其中程序计数器,虚拟机栈,本地方法区都是随着线程而生,随线程而灭,所以这几个区域就不需要过多考虑回收问题.但是堆和方法区就不一样了,只有在程序运行期间我们才知道会创建哪些对象,这部分内存的分配和回收都是动态的.垃圾收集器所关注的就是这部分内存. 一 对象

  • JVM垃圾收集器详解

    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物.事实上,GC的历史远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言.当List还在胚胎时期时,人们就在思考GC需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 一.哪些内存需要回收? 从JVM区域结构看,可将这些区域划分为"静态内存"和"动态内存"两类.程序计数器.虚拟机栈.本地方法3个区域

  • 面试官:怎么做JDK8的垃圾收集器的调优(面试常问)

    看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在JDK8中有Serial收集器.Parallel收集器.CMS收集器.G1收集器这么几种收集器,需要根据实际硬件配置和业务需求进行选择调优. 如此浅显的回答,无法让面试官达到深入的要求,肯定不能满足面试官强烈的需求,果不其然面试官又追问到:如果是桌面应用,内存占用也就100MB,应该选择哪种垃圾收集器呢?我快速的回答:Serial收集器.看着面试官期待的眼神,我又详细

  • 面试官问订单ID是如何生成的?难道不是MySQL自增主键

    一个美女面试官坐到我的对面,发光logo的MacBook也挡不住她那圆润可爱的脸庞. 程序媛本就稀有,美女面试官更是难寻. 这么温柔可爱的面试官,应该不会为难我吧.嗯,应该是的,毕竟我这么帅气,面试可能就是走个过场.美女面试官是不是单身?毕竟程序员都不善交流,因为我也是单身,难道我的姻缘就在此注定.孩子的名字我都想好了.一冰!好名字. 面试官: 小伙子,你低着头笑什么呐.开始面试了,你知道订单ID是怎么生成的吗? 啥?订单ID怎么生成?美女怎么不按套路出牌!HashMap实现原理,我已经倒背如流

  • 吊打Java面试官!整理了一周的Spring面试大全(附答案)

    目录 Q1:什 么 是 spring? Q2:使 用 Spring 框 架 的 好 处 是 什 么 ? Q3:使 用 Spring 缺点是什么? Q4:IoC 是什么? Q5:IOC的优点是什么 Q6:IoC 容器初始化过程? Q7:依赖注⼊的实现方法有哪些? Q8:依赖注入的相关注解? Q9:依赖注入的过程? Q10:Bean 的生命周期? Q11:Bean 的作⽤范围? Q12:如何通过 XML ⽅式创建 Bean? Q13:Spring 有几种配置方式? Q14:如何用基于 XML 配置的

  • 面试官:Java中new Object()到底占用几个字节

    前言 我们来分析一下堆内布局以及Java对象在内存中的布局吧. 对象的指向 先来看一段代码: package com.zwx.jvm; public class HeapMemory { private Object obj1 = new Object(); public static void main(String[] args) { Object obj2 = new Object(); } } 上面的代码中,obj1 和obj2在内存中有什么区别? 我们先来回忆一下JVM系列1的文章中有

  • 吊打Java面试官之Lambda表达式 Stream API

    目录 一.jdk8新特性简介 二.Lambda表达式 简单理解一下Lambda表达式 Lambda表达式的使用 三.函数式接口 1.什么是函数式接口 2.如何理解函数式接口 3.Java内置四大核心函数式接口 四.方法引用与构造器引用 方法引用 构造器引用和数组引用 五.Stream API 1.Stream API的说明 2.为什么要使用Stream API 3.创建Stream的四种方式 4.Stream的中间操作及其测试 5.Stream的终止操作及其测试 六.Optional类的使用 O

  • java性能优化四种常见垃圾收集器汇总

    目录 前言 常见的垃圾回收器和算法 serial 串行垃圾收集器 Parallel 多线程垃圾收集器 CMS 收集器 G1 收集器 显式垃圾收集 前言 本篇文章我们来具体看看如何选择合适的垃圾收集器.每种垃圾收集器都有其不同的算法实现和步骤,下面我们简单描述下我们常见的四种垃圾收集器的算法过程,感兴趣的同学们最好先看下以下的两篇文章去增加理解.分别介绍了一些垃圾回收的基本概念,和各种垃圾回收器回收的过程,内容重复,本章不会在去单独讲解一遍.所以本章做一些归纳总结. JVM GC 垃圾收集梳理总结

  • 详解Java面试官最爱问的volatile关键字

    本文向大家分享的主要内容是Java面试中一个常见的知识点:volatile关键字.本文详细介绍了volatile关键字的方方面面,希望大家在阅读过本文之后,能完美解决volatile关键字的相关问题.  在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度,而以volatile关键字作为一个小的切入点,往往可以一问到底,把Java内存模型(JMM),Java并发编程的一些特性都牵扯出来,深入地话还可以考察JVM底层实现以及操作系统的相关知识. 下面我们以一次假想的面试过

  • Java面试官最喜欢问的关键字之volatile详解

    前言 笔者去年面试过几家公司,基本上每家公司都会问到volatile,甚至有的公司每轮面试的时候都会问到.面试官这么喜欢问volatile就是因为这个关键字涉及到的知识点较多比如Java内存模型.内存屏障.happen-befor等知识,可以继续挖掘到系统指令.超线程等知识. Java内存模型(JMM) volatile是Java虚拟机提供的最轻量的同步机制,但很难被正确的理解与使用,通过学习Java内存模型对volatile专门定义的一些特殊访问规则,或许会对理解volatile有一定帮助.

  • 一口气说出Java 6种延时队列的实现方法(面试官也得服)

    五一期间原计划是写两篇文章,看一本技术类书籍,结果这五天由于自律性过于差,禁不住各种诱惑,我连电脑都没打开过,计划完美宣告失败.所以在这能看出和大佬之间的差距,人家没白没夜的更文,比你优秀的人比你更努力,难以望其项背,真是让我自愧不如. 知耻而后勇,这不逼着自己又学起来了,个人比较喜欢一些实践类的东西,既学习到知识又能让技术落地,能搞出个demo最好,本来不知道该分享什么主题,好在最近项目紧急招人中,而我有幸做了回面试官,就给大家整理分享一道面试题:"如何实现延时队列?". 下边会介绍

  • 当面试官问我ArrayList和LinkedList哪个更占空间时,我是这么答的(面试官必问)

    前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的最多的工具类了,也是面试中几乎必问的,LinkedList可能用的少点,但大多数的面试也会有所涉及,尤其是关于这两者的比较可以说是家常便饭,所以,无论从使用上还是在面试的准备上,对于这两个类的知识点我们都要有足够的了解. ArrayList ArrayList是List接口的一个实现类,底层是基于数

随机推荐