0.前言
1.Serial垃圾收集器
1.1Serial垃圾收集器优缺点及实用场景
1.2Serial垃圾收集器的开启和应用
2.ParNew垃圾收集器
2.1ParNew垃圾收集器优缺点及实用场景
2.2ParNew垃圾收集器的开启和应用
3.Parallel垃圾收集器
3.1Parallel垃圾收集器优缺点及实用场景
3.2Parallel垃圾收集器的开启和应用
4.CMS垃圾收集器
4.1CMS垃圾收集器优缺点及实用场景
4.2CMS垃圾收集器的开启和应用
4.3CMS垃圾收集器的应用注意事项
5.G1垃圾收集器
5.1G1垃圾收集器优缺点及实用场景
5.2G1垃圾收集器的开启和应用
6.垃圾收集器的算法汇总
0.前言
咱们之前在深刻了解JVM(五)——垃圾收集算法中介绍过各种垃圾收集的算法,然而GC算法是内存回收的实践,垃圾收集器是算法的落地实现。首先到目前为止并没有完满的垃圾收集器,咱们只有针对适合的场景,采纳适当的垃圾收集器。
1.Serial垃圾收集器
Serial垃圾收集器是最根本,倒退最悠久的单线程垃圾收集器。咱们先来看一下它的垃圾收集过程图。
执行流程:假如咱们的java过程的堆内存曾经被耗尽,当Serial垃圾收集器启动的时候,它会进行所有用户线程,达到一个STOP-THE-WORLD(会有较长的进展)的状态,等到垃圾收集结束之后,再运行用户线程进行工作。
串行收集器是最古老,最稳固且效率最高的收集器,只应用一个垃圾收集器去回收会在其收集的时候产生较长的进展,尽管要暂停所有其它的线程,然而它最简略高效,对于限定单个CPU环境来说,没有线程交互的开销能够取得最高的单线程垃圾收集效率。
1.1Serial垃圾收集器优缺点及实用场景
长处:实现简略,稳固,单线程效率最高
毛病:会有较长时间的进展,用户体验差
实用场景:单CPU或小内存,较小的程序
1.2Serial垃圾收集器的开启和应用
-XX:+UseSerialGC 开启Serial垃圾收集器
-XX:+PrintCommandLineFlags 启动服务的时候,查看程序应用的默认JVM参数
开启上述参数后,会应用Serial(Young区)+Serial(Old区)的组合。
新生代采纳复制算法,老年代采纳标记整顿算法。
当咱们把上述参数输出IDEA之后,在启动服务的第一行,就会呈现咱们曾经开启了Serial垃圾收集器。
2.ParNew垃圾收集器
ParNew垃圾收集器其实就是多线程版本的Serial垃圾收集器,其余的行为和Serial垃圾收集器截然不同,ParNew收集器在垃圾收集过程中同样也须要暂停所有工作线程(STOP-THE-WORLD)。
2.1ParNew垃圾收集器优缺点及实用场景
长处:实现简略,稳固,在多cpu的状况下,比单线程效率更高,进展工夫短
毛病:也会有肯定的进展,用户体验差
实用场景:多CPU,谋求进展工夫,须要疾速响应的场景,如互联网利用
2.2ParNew垃圾收集器的开启和应用
-XX:+UseParNewGC 开启ParNew垃圾收集器
-XX:+PrintCommandLineFlags 启动服务的时候,查看程序应用的默认JVM参数
开启上述参数后,会应用ParNew(Young区)+Serial(Old区)的组合。新生代采纳复制算法,老年代采纳标记整顿算法。
3.Parallel垃圾收集器
Parallel垃圾收集器相似于ParNew垃圾收集器,也是一个新生代的垃圾收集器,应用复制算法,也是一个并行的多线程垃圾收集器,不过它的关注点是达到可管制的吞吐量
(吞吐量:cpu用于运行用户代码的工夫和cpu耗费的总工夫的比值 )
(吞吐量公式:用户代码的工夫 / (用户代码的工夫)+(垃圾回收的占用工夫))
比方程序运行100分钟,垃圾收集器运行1分钟,吞吐量就是99%。
3.1Parallel垃圾收集器优缺点及实用场景
长处:多线程收集速度快,能够管制吞吐量
毛病:如果参数设置地过于小,线程之间一直切换意味着须要额定的开销,从而垃圾回收和用户线程的总工夫将会缩短。
应用场景:多CPU,须要大吞吐量,如后盾计算利用
3.2Parallel垃圾收集器的开启和应用
-XX:+UseParallelGC 开启Parallel垃圾收集器
-XX:+PrintCommandLineFlags 启动服务的时候,查看程序应用的默认JVM参数
因为parallel垃圾收集器是管制吞吐量的,所以还有几个重要的参数。
-XX:+UseAdaptiveSizePolicy 设置Parallel Scavenge收集器具备自适应调节策略。
在这种模式下,年老代的大小、Eden和Survivor的比例、降职老年代的对象年龄等参数会被主动调整,已达到在堆大小、吞吐量和进展工夫之间的平衡点。
在手动调优比拟艰难的场合,能够间接应用这种自适应的形式,仅指定虚拟机的最大堆、指标的吞吐量(GCTimeRatio)和进展工夫(MaxGCPauseMIllis),让虚拟机本人实现调优工作。
-XX:ParallelGCThreads设置年老代并行收集器的线程数。个别的最好与CPU数量相等,以防止过多的线程数影响垃圾回收性能。88
默认状况下,当CPU数量小于8个,ParallelGCThreads的值等于CPU数量。
当CPU数量大于8个时,线程数为3 + ((5*CPU_Count)/8)。
-XX:MaxGCPauseMillis设置垃圾收集器最大进展工夫(即STW的工夫)。单位是毫秒。
为了尽可能地把进展工夫管制在MaxGCPauseMillis以内,收集器在工作时会调整Java堆大小或者其余一些参数。
对于用户来讲,进展工夫越短体验越好。然而在服务器端,咱们重视高并发,整体的吞吐量。所以服务器端适宜Parallel,进行管制。
该参数审慎应用。
-XX:GCTimeRatio :取值范畴(0,100)垃圾收集工夫占总工夫的比例(=1 / (N + 1))用于掂量吞吐量的大小。默认值99,也就是垃圾回收工夫不超过1%。
MaxGCPauseMIllis越大,这个比例就越高。
4.CMS垃圾收集器
CMS(Concurrent Mark Sweep:并发标记革除)是一种以最短回收进展工夫为指标的收集器。它的垃圾收集线程和用户线程一起执行,将STW的工夫达到最短,采纳标记-革除算法。
咱们从图能够看出,cms垃圾收集器一共分四个步骤:
初始标记:须要stop the world,应用可达性剖析算法标记,速度很快
并发标记:多个线程同时并发标记
从新标记:修改并发标记期间因为用户程序持续运作而导致的变动
并发革除:并发进行革除
4.1CMS垃圾收集器优缺点及实用场景
长处:并发收集,低进展
毛病:对cpu资源敏感,无奈解决浮动垃圾,基于标记革除,会产生碎片
实用场景:实用于堆内存大,CPU核数多的服务器端利用,这类利用及其器重服务器响应速度,心愿零碎进展工夫最短。
4.2CMS垃圾收集器的开启和应用
-XX:+UseConcMarkSweepGC 开启CMS垃圾收集器
-XX:+PrintCommandLineFlags 启动服务的时候,查看程序应用的默认JVM参数
4.3CMS垃圾收集器的应用注意事项
1.因为并发执行,CMS在收集与利用线程同时执行的时候,会减少堆内存的占用。也就是说,CMS垃圾收集器要在老年代堆内存用尽之前实现垃圾回收,否则CMS垃圾收集器回收失败,会触发担保机制,串行老年代收集器将会以STWGC的形式进行一次GC,造成大量进展工夫。
2.标记革除算法无奈整顿碎片,老年代会随着工夫的流逝而用尽内存,最初不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFullGCsBeForeCompation来指定多少次CMS垃圾收集之后,进行一次压缩GC。
5.G1垃圾收集器
在介绍G1收集器之前,咱们先总结一下以前的垃圾收集器的共同点,再来看G1。
年老代和老年代是各自独立且间断的内存块。
年老代收集应用eden+S0+S1进行复制算法。
老年代收集器必须扫描整个老年代区域
都是以尽可能少而疾速地执行GC为设计准则。
这时,咱们来看G1:
G1利用在多处理器和大容量内存环境中,在实现高吞吐量的同时,尽可能地满足垃圾收集器暂停工夫的要求。另外,它还具备以下个性:
像CMS垃圾收集器一样,能与工作线程同时并发执行。
整顿空间速度更快。
不心愿就义大量的吞吐性能。
不须要更大的JAVA Heap。
G1垃圾收集器的初衷是为了取代CMS垃圾收集器,它同CMS相比,在以下方面体现更杰出。
G1是一个采纳标记-整顿算法,不会产生很多内存碎片。
G1能充分利用多CPU硬件劣势,缩短STW工夫
宏观上G1不辨别新生代和老年代,把内存划分成了多个独立的子区域。能够看做围棋的棋盘图。
G1收集器外面的整个内存区域都混合在一起了,但其自身依然在小范畴内仍要进行年老代和老年代的辨别。
G1尽管也是分代收集器,但整个内存分区不在物理上进行隔离,每个区域会随着对象的变动进行老年代和新生代之间的转化。
G1大略就把内存分成了如图所示
各个区域也由原来的产生了变动:
针对Eden区域进行收集,Eden区耗尽后会被触发,次要是小区域收集+造成间断的内存块,防止内存碎片
假如Eden区域内存不够,局部对象降职到Survivor区域,如果Survivor区域不够,字节进入老年代。
执行过程:和CMS一样
初始标记:须要stop the world,应用可达性剖析算法标记,速度很快
并发标记:多个线程同时并发标记
从新标记:修改并发标记期间因为用户程序持续运作而导致的变动
并发革除:并发进行革除
5.1G1垃圾收集器优缺点及实用场景
长处:
G1不会产生内存碎片
G1效率高
G1能够准确管制进展
毛病:
G1 须要记忆集 (具体来说是卡表)来记录新生代和老年代之间的援用关系,这种数据结构在 G1 中须要占用大量的内存,可能达到整个堆内存容量的 20% 甚至更多。而且 G1 中保护记忆集的老本较高,带来了更高的执行负载,影响效率。
5.2G1垃圾收集器的开启和应用
-XX:+UseG1GC 开启G1收集器
-XX:+PrintCommandLineFlags 启动服务的时候,查看程序应用的默认JVM参数
另外 G1还有以下辅助参数。
-XX:G1HeapRegionSize=n: 设置G1区域的大小,值是2的次数幂,范畴是1MB~32MB
-XX:MaxGCPauseMillis GC最大进展工夫,单位是毫秒
-XX:InitiatingHeapOccupancyPercent:堆占用了多少个的时候就触发GC,默认为45
-XX:ParallelGCThreads STW期间,并行GC线程数
-XX:G1ReservePercent 默认10%。也就是老年代会预留10%的空间来给新生代的对象降职.设置闲暇的空间预留内存百分比,以升高OOM的危险。
6垃圾收集器的算法汇总
参数 | 新生代垃圾收集器 | 新生代算法 | 老年代垃圾收集器 | 老年代算法 |
---|---|---|---|---|
-XX:+UserSerialGC | SerialGC | 复制 | SerialOldGC | 标记整顿 |
-XX:+UseParNewGC | ParNew | 复制 | SerialOldGC | 标记整顿 |
-XX:+UseParallelGC | Parallel | 复制 | ParallelOld | 标记整顿 |
-XX:+UseConcMarkSweepGC | ParNew | 复制 | CMS+SerialOld | 标记革除 |
-XX:+UseG1GC | G1整体上采纳标记-整顿算法 | 部分是复制算法,不会产生碎片 |
总结:
明天咱们介绍了各种垃圾收集器的特点,收集过程,收集算法和应用场景,心愿咱们能多多应用,把握垃圾收集器。