一张图让你看懂JVM之垃圾回收器详解

前言

感谢读者的反馈,在👆图中更新了新生代Eden区以及两个Survivor区的默认空间占比的分配表示,这里按照10等份区分8/10、1/10、1/10分别表示8:1:1的关系,会更清晰点。新生代所采用的“标记-复制-清除”的算法进行垃圾回收,以及分代回收算法中老年代如何为这种空间分配比所提供担保策略,在前文《一张图让你看懂JVM之垃圾回收算法详解》中有比较详细的叙述,大家可以看下,这里就不再赘述。

另外一个遗留问题是关于direct memoryn****ative momery区别的问题,首先可以确认的是这两种称呼的内存肯定都是堆外内存,是不受JVM自动垃圾回收机制管理的。

从更为细致的角度区分,目前有一种解释是这样表述的:"direct memory,在Java的上下文中特指Java程序通过一组特定的API访问native memory,而这组API主要是通过DirectByteBuffer暴露出来的。而Native memory则是一个相对通用的概念,因为在Hotspot VM中,不受GC管理的内存都是native memory,direct memory只限定在特定的访问Native memory的做法,二者并不完全等价"。关于这个两个概念的解释,如果有更好的区分大家可以给我留言,这个问题实际上并不关键,只是有同学有疑问,这里就稍微解释下了。

回到本文的主题,在之前文章中我们对Java垃圾收集算法的特点有了一定的认识,但是对于JVM而言算法并不是实现,要进行GC操作JVM是通过特定的垃圾回收器来完成的,在👆图中已经把目前比较常用的垃圾回收器,以及这些回收器分别适用于那些内存空间作了一个初步的展示,但是这些垃圾回收器的特点是什么?有什么样的优缺点?在本文中和大家探讨下。

垃圾回收器

垃圾收集器是垃圾收集算法的具体实现,由于Java虚拟机规范并没有对垃圾收集器如何实现进行明确的规定,所以不同的JVM厂商以及不同虚拟机版本所提供的垃圾收集器都可能会有较大的差别,并且一般也都会提供对应的参数,供用户根据自己的应用特点组合出各个内存区块,主要是新生代、老年代所使用的收集器。

本文以JDK1.7 Update14之后的Hotspot虚拟机,也是目前使用最为广泛的虚拟机为基础,和大家一起看看都有那些垃圾收集器,以及它们的特点是什么。

在详细讨论具体垃圾收集器之前,我们先看下这些收集器所适用的范围,以及它们的组合配对关系。

具体如下图所示:

上图展示了JDK1.7+后,Hotspot JVM的所有垃圾收集器以及它们适用的“代”,适合新生代的垃圾收集器有:Serial、ParNew、Parallel Scavenge、G1。适合年老代的垃圾收集器有:CMS、Serial Old、Parallel Old、G1。它们之间的组合关系如上图连线(粗线相连的是最佳组合),其中G1是JDK1.7 Update14这个版本中正式提供的商业收集器,它可以同时适用于新生代和年老代。

实践上在JDK1.7以后其实是可以统一采用G1收集器的(作者目前所在公司已经全部使用G1收集器),至于G1具体的特性,在本文稍后的内容中详细讲解。

- JAVA_OPTS=-Xms4g -Xmx4g -Xmn2g -XX:MaxDirectMemorySize=1g -XX:-
OmitStackTraceInFastThrow -XX:+UseG1GC -XX:G1ReservePercent=25 -
XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -
XX:+DisableExplicitGC -verbose:gc -Xloggc:/opt/gc_%p.log -XX:+PrintGCDetails -
XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy -
XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m

虽然实践上已然可以同一采用G1了,但是作为基础知识,我们还是对这些具体垃圾收集器有一个比较深刻的认识会比较好。下面就依次讨论下这些垃圾收集器的特点是什么吧!

Serial(新生代-串行-收集器)

Serial是一个比较古老的收集器,而且是一个单线程的收集器,这种收集器在进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束(采用的是复制算法)。所以试想下在互联网高并发的场景下采用这样的收集器显然是不可以的,所以我们目前在做后端服务时,不可能会用到这款收集器。

因为其简单、单线程的特点用在Java桌面程序场景会比较合适,但是大家也都知道目前采用Java开发桌面程序已经很少见了,所以大家对此了解就行。

其工作示意图如下:

ParNew(新生代-并行-收集器)

Parnew收集器是Serial的多线程版本,除了多线程收集外,其余部分与Serial相比并没有多大的差别,由于其可以与CMS收集器配合使用,所以在JDK1.7之前,对于Java服务应用来说是首选的新生代收集器。

示意图如下:

这种收集器与Serial一样,在进行垃圾回收时也会暂停所有用户工作线程,只是它采取了多线程回收,所以回收的速度会比Serial快,从而将卡顿时间缩短。

Parallel Scavenge (新生代-并行-收集器)

Parallel Scavenge也是一个新生代收集器,采用的也是多线程,以及复制收集算法,与其他同类型收集器不同的是,它的关注点是达到一个可控制吞吐量的目标,吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收的时间),假设虚拟机总共运行了100分钟,其中垃圾回收花了一分钟,那么吞吐量就是99%。高吞吐量的目的是为了高效的利用CPU时间,从而尽快的完成程序运算任务,主要适合后台运算不需要有太多交互的应用场景。

该收集器提供的控制参数有:

MaxGCPauseMillis:GC时间的最大值。

GCTimeRatio:GC时间占用总时间的比例。

UseAdaptiveSizePolicy:这个参数则是开启GC内存分配的自适应调整策略。可以自动调节,新生代的大小、Eden与Survivor的比例、晋升老年代对象的年龄。

Serial Old(年老代-串行-收集器)

Serial Old 收集器就是Serial的老年代版本,是一个单线程的,垃圾收集算法采用标记-整理算法的收集器。

Parallel Old(年老代-并行-收集器)

Parallel Old收集器是Parallel Scavenge的老年代版本,是多线程,采用标记-整理算法的收集器。

CMS(年老代-并行-收集器)

CMS(Concurrent Mark-Sweep)是一款以获取最短回收停顿时间为目标的收集器。比较适合互联网响应式应用场景,采用的是“标记-清除”算法。

其收集过程如下图所示:

如图所示,在初始标记和重新标记两个步骤,也会和Serial 一样暂停所有用户线程。

G1收集器

G1(Garbage First)是目前最为前沿的垃圾回收器,在前面的内容中已经提过JDK1.8以后的生产实践新生代、年老代都可以采用G1作为垃圾回收器。其采用的收集算法是”标记-清除-整理“,所以不会产生内存碎片。

后记

在实践中关于GC收集器的选择,看目前来看,如果是互联网高并发场景的服务器端应用,可以统一使用G1就行。而如果是其他的应用场景,可能就需要根据合适的场景进行组合选择了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容