面试官:怎么做JDK8的垃圾收集器的调优?

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

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

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

文章持续更新,微信搜索「万猫学社第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

Serial收集器

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

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

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

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

文章持续更新,微信搜索「万猫学社第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

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收集器。看着面试官期待的眼神,我又详细解释到:

文章持续更新,微信搜索「万猫学社第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

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收集器。看着面试官期待的眼神,我又详细解释到:

文章持续更新,微信搜索「万猫学社第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。

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。

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

文章持续更新,微信搜索「万猫学社」第一时间阅读。

关注后回复「电子书」,免费获取12本Java必读技术书籍。

微信公众号:万猫学社

微信扫描二维码

关注后回复「电子书」

获取12本Java必读技术书籍

面试官:怎么做JDK8的垃圾收集器的调优?的更多相关文章

  1. 7种 JVM 垃圾收集器特点、优劣势及使用场景(多图)

    7种 JVM 垃圾收集器特点.优劣势及使用场景(多图)  mp.weixin.qq.com 点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.常见垃 ...

  2. 7种JVM垃圾收集器特点,优劣势、及使用场景

    今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...

  3. 【面试 JVM】【第六篇】JVM调优

    六部分内容: 一.内存模型 1.程序计数器,方法区,堆,栈,本地方法栈的作用,保存那些数据 可以画个大图出来,很清晰 jvm内存模型主要指运行时的数据区,包括5个部分. 栈也叫方法栈,是线程私有的,线 ...

  4. 【面试】足够“忽悠”面试官的『Spring事务管理器』源码阅读梳理(建议珍藏)

    PS:文章内容涉及源码,请耐心阅读. 理论实践,相辅相成 伟大领袖毛主席告诉我们实践出真知.这是无比正确的.但是也会很辛苦. 就像淘金一样,从大量沙子中淘出金子一定是一个无比艰辛的过程.但如果真能淘出 ...

  5. 查看JVM使用的默认的垃圾收集器

    一.查看步骤 cmd执行命令: java -XX:+PrintCommandLineFlags -version 输出如下(举例): 针对上述的-XX:UseParallelGC,这边我们引用< ...

  6. Java垃圾收集器——Parallel、G1收集器日志分析及性能调优示范

    开发过程中,经常需要对GC的垃圾收集器参数不断的进行动态调整,从而更充分的压榨机器性能,提升应用效率.本文将从常见的Parallel/G1垃圾收集器的GC日志着手,分析GC日志的具体含义,以及示范如何 ...

  7. 3-JVM垃圾回收算法和垃圾收集器

    垃圾回收算法和垃圾收集器 1.什么是垃圾回收 对于内存当中无用的对象进行回收,如何去判断一个对象是不是无用的对象. 引用计数法: 每个对象中都会存储一个引用计数,每增加一个引用就+1,消失一个引用就- ...

  8. 面试官:"谈谈分库分表吧?"

    原文链接:面试官:"谈谈分库分表吧?" 面试官:“有并发的经验没?”  应聘者:“有一点.”   面试官:“那你们为了处理并发,做了哪些优化?”   应聘者:“前后端分离啊,限流啊 ...

  9. 一个HashMap能跟面试官扯上半个小时

    一个HashMap能跟面试官扯上半个小时 <安琪拉与面试官二三事>系列文章 一个HashMap能跟面试官扯上半个小时 一个synchronized跟面试官扯了半个小时 一个volatile ...

随机推荐

  1. vue-watch : 深度监控的语法格式--检测数据的tabledata这个数组的变化

    watch:{ tableData:{ handler(a,b){ this.tableData= a; console.log(a ,b) }, deep:true }, }

  2. Netty 学习笔记(1) ------ Hello World

    服务端启动流程 package com.example.netty; import com.example.netty.handler.HelloServerHandler; import io.ne ...

  3. 前端学习(八):CSS

    进击のpython ***** 前端学习--CSS 现在的互联网前端分为三层: HTML:超文本标记语言.从语义的角度描述页面结构 CSS:层叠样式表.从审美的角度负责页面样式 JS:Javascri ...

  4. 如何用Excel进行预测分析?

      [面试题] 一个社交APP, 它的新增用户次日留存.7日留存.30日留存分别是52%.25%.14%. 请模拟出来,每天如果日新增6万用户,那么第30天,它的日活数会达到多少?请使用Excel进行 ...

  5. 手牵手,从零学习Vue源码 系列一(前言-目录篇)

    系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 手牵手,从零学习Vue源码 系列三(虚拟DOM篇) 陆续更新中... 预计八月中旬更新 ...

  6. emwin显示汉字使用vs studio仿真和使用keil编写烧录的不同

    我用emwin是在新唐的开发板上练习的,所有我就去官网下了开发板的资料,别的开发板应该也有对应的资料,这些软件网上应该很容易搜得到 然后用GUIBuilder构建一个界面,再用FontArchitec ...

  7. Python打印到屏幕_读取键盘输入

    Python打印到屏幕_读取键盘输入: print( ): 打印输出括号中的值 print("hello") # hello strs = 'hello' print(" ...

  8. Seaborn实现回归分析

    import numpy as np import pandas as pd from scipy import stats,integrate import matplotlib.pyplot as ...

  9. 一本通 高手训练 1781 死亡之树 状态压缩dp

    LINK:死亡之树 关于去重 还是有讲究的. 题目求本质不同的 具有k个叶子节点的树的个数 不能上矩阵树. 点数很少容易想到装压dp 考虑如何刻画树的形状 发现一个维度做不了 所以. 设状态 f[i] ...

  10. luogu P4008 [NOI2003]文本编辑器 splay 块状链表

    LINK:文本编辑器 这个东西感觉块状链表写细节挺多 (块状链表本来就难写 解释一下块状链表的做法:其实是一个个数组块 然后利用链表给链接起来 每个块的大小为sqrt(n). 这样插入删除的时候直接暴 ...