脚本宝典收集整理的这篇文章主要介绍了JVM垃圾收集器专题,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
HotSpot垃圾回收器有多个,可以配合使用。
简写为STW,也叫全局停顿,Java代码停止运行,native代码继续运行,但不能与JVM进行交互。
STW主要是为了GC操作的准确性和效率。用户线程不停止的话,会不断有新对象和垃圾对象产生,假设没有STW,会导致GC时间过长,错误清理新对象等情况。
原因:多半由于垃圾回收导致;也可能是Dump线程、死锁检查、Dump堆等导致。
危害:服务停止、没有响应;主从切换(对于高可用环境,如果停顿时间过长,会引发主从之间的切换)、危害生产安全。
因此,尽量缩短Stop the world的时间。
并行收集:指多个垃圾收集线程并行工作,但是在收集的@R_512_2638@,用户线程(你的业务线程)还是处于等待状态的
并发收集:指用户线程与垃圾收集线程同时工作
CPU用于运行用户代码的时间与CPU总消耗时间的比值
公式:运行用户代码时间/(运行用户代码时间+垃圾收集时间)
Serial 收集器是最基本、发展历史最悠久的收集器,采用复制算法。采用单线程操作,收集过程中全程STW。
适用场景有:
-client
模式运行时,默认使用的就是Serial(java -client -jar
运行)Serial收集器的多线程版,除使用多线程以外,其他和Serial收集器一样,包括:JVM参数、Stop the world表现、垃圾收集算法都是一样的。可使用 -XX:ParallelGCThreads
设置垃圾收集的线程数。主要和CMS垃圾收集器配合使用。
ParallelScavenge收集器,是吞吐量优先收集器,也是采用复制算法,也是多线程的。执行过程与ParNew收集器类似。
Parallel Scavenge收集器适用于注重吞吐量的场景。
可以达到一个可控制的吞吐量
-XX:MaxGCPauSEMillis
:控制最大的垃圾收集停顿时间(尽力)
-XX:GCTimeRatio
:设置吞吐量的大小,取值0-100,系统花费不超过1/(1+n)的时间用于垃圾收集
自适应GC策略:可用-XX:+UseAdptiveSizepolicy
打开
Serial Old收集器是Serial收集器的老年代版本,单线程,采用的是标记-整理算法,垃圾收集过程Stop The World。
可以与上面三个新生代收集器配合使用;当CMS收集器出现故障时,作为后备处理器。
Parallel Old收集器是Parallel Scavenge收集器的老年代版本,只能与Parallel Scavenge收集器配合使用,同样是注重对吞吐量要求较高的场景。
Parallel Old收集器,采用多线程,标记-整理算法,垃圾收集过程Stop The World。
CMS: Concuerrent mark sweep(并发标记收集器),采用标记-清除算法。
CMS执行过程的七个阶段:
-XX:-CMSPRecleaningEnabled
关闭并发预清理阶段,默认打开。CMSScheduleEdenSizeThreshold
的阈值(默认2M)时,才会执行该阶段。主要作用是允许我们能够控制预清理阶段的结束时机。优点:STW时间较短,大多数过程并发执行。
缺点:
UseCMSCompactAtFullCollection
:在完成Full GC后是否要进行内存碎片整理,默认开启。CMSFullGCsBeforeCompaction
:进行几次Full GC后就进行一次内存碎片整理,默认是0。CMS适用于希望系统停顿时间短,响应速度快的场景,例如Web。
1、首先,CMS是一个关注停顿时间,以回收停顿时间最短为目标的垃圾回收器。并发预处理阶段做的工作是标记,重标记需要STW(Stop The World),因此重标记的工作尽可能多的在并发阶段完成来减少STW的时间。此阶段标记从新生代晋升的对象、新分配到老年代的对象以及在并发阶段被修改了的对象。 2、并发可中断预清理(Concurrent precleaning)是标记在并发标记阶段引用发生变化的对象,如果发现对象的引用发生变化,则JVM会标记堆的这个区域为Dirty Card。那些能够从Dirty Card到达的对象也被标记(标记为存活),当标记做完后,这个Dirty Card区域就会消失。CMS有两个参数:CMSScheduleRemarkEdenSizeThreshold、CMSScheduleRemarkEdenPEnetration,默认值分别是2M、50%。两个参数组合起来的意思是预清理后,eden空间使用超过2M时启动可中断的并发预清理(CMS-concurrent-abortable-preclean),直到eden空间使用率达到50%时中断,进入重新标记阶段。
G1(Garbge First),面向服务端应用,可以同时用于新生代和老年代。
G1收集器使用Region作为单位,包括四种类型,分别为Eden、Survior、Old和Humongous,通过参数-XX:G1HeapRegionSize
指定Region的大小,取值范围为1MB ~ 32 MB之间。
前三种Region仍然是伊甸园、存活区、老年代,Humongous用来存储大对象,对象过大可以存储到连续的Humongous中。Old和Humongous同属于老年代。
G1收集器的设计思想:将内存分成很多小块(Region),跟踪每个Region中垃圾堆积的价值大小,构建一个优先列表,根据允许的收集时间,优先回收价值最高的Region。其中价值大小指的是回收该Region能获得的空间大小以及回收所需要的时间成本。
主要分为三种,Young GC、Mixed GC、Full GC。
所有Eden Region都满了的时候,就会触发Young GC。
老年代大小占整个堆的百分比达到一定阈值(可用-XX:InitiatingHeapOccupancyPercent指定,默认45%),就触发Mixed GC,会回收所有 Young Region,同时回收部分 Old Region。
执行过程分为四步:
初始标记:跟CMS类似,标记处GC Roots能直接关联到的对象,存在短暂STW。
并发标记:跟CMS类似,找出所有GC Roots能关联的对象。并发执行,不会触发STW。
最终标记:更新在并发标记期间引起的变更,存在STW。
筛选回收:首先对各个Region的回收价值和成本排序,根据用户所期望的停顿时间指定回收计划,筛选出合适的Region回收。停顿时间:MaxGCPauseMillis。
回收过程:将Region的存活对象复制到空闲Region中,然后删除原Region,是复制算法,无内存碎片,过程存在STW。
G1收集器Mixed GC除了并发标记以外的过程都是STW的,由于一次只回收一部分Region,所以停顿时间可控。
复制对象内存不够,或者无法分配足够的内存(例如大对象无法分配连续的内存),就会触发Full GC。Full GC机制采用单线程的Serial Old模式。
因此G1收集器的优化原则是,尽可能的减少Full GC。
上面三点大白话总结:多留一点内存,有内存可以分配;有垃圾早点回收;垃圾回收快点。
G1收集器作用于整个堆,可以控制停顿时间(MaxGCPauseMillis=200),并且没有内存碎片。
G1收集器占用内存较大(通常需要6G以上),可以代替CMS收集器。对于JDK8,主要根据内存选择,内存小于6G,选CMS;内存大于6G,使用G1。CMS在JDK9中被废弃,高于JDK8的版本可以选G1。
截止目前JDK14依然处于实验状态
Shenandoah(IBM开发,是ZGC竞品,进入OpenJDK,被oracle JDK12剔除。)
ZGC(一款革命性的收集器)
Epsilon:不干活的垃圾收集器。
从理论出发主要有下面几点。
以上是脚本宝典为你收集整理的JVM垃圾收集器专题全部内容,希望文章能够帮你解决JVM垃圾收集器专题所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。