更深入的了解JAVA:内存结构---垃圾回收一主要记录了收集器被触发的条件,这是JVM性能调优的基础。如果您想做到有的放矢或者遇到问题时更精准的把握问题,这些应该需要了解。
下面秉承上篇记录一下垃圾收集器。
名称 | 线程 | 新生代停顿 | 老年代停顿 | 老年代压缩 | FullGC次数 |
Seria | 单线程 | 是 | 是 | Full GC时整理 | 多 |
Parallel | 多线程 | 是 | 是 | Full GC时整理 | 多 |
CMS | 多线程 | 是 | 否 | UseCMSCompactAtFullCollection | 少 |
G1 | 多线程 | 是 | 否 | 几乎不产生碎片 | 最少 |
ParNew | 多线程 | 是 | ---- |
| 专注新生代 |
1.Serial收集器
单线程垃圾收集器、最基本、发展最悠久。它的单线程的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。偶尔用在桌面应用中。
-XX:+UseSerialGC:设置串行收集器。
2.ParNew收集器
可多线程收集垃圾,收集新生代,使用收集算法
3.Parallel收集器
多线程收集垃圾,收集新生代,使用收集算法。Parallel收集器更关注系统的吞吐量,可以通过参数来打开自适应调节策略。
吞吐量:CPU用于运行用户代码的时间与CPU消耗的总时间的比值。
吞吐量 = (执行用户代码时间)/(执行用户代码时间+垃圾回收占用时间)
-XX:+UseParallelGC:设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集,而年老代仍使用串行收集。
-XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收。此值建议配置与CPU数目相等。
-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。JDK6.0开始支持对年老代并行收集。
-XX:MaxGCPauseMillis=100:设置每次年轻代垃圾回收的最长时间(单位毫秒)。如果无法满足此时间,JVM会自动调整年轻代大小,以满足此时间。但最大停顿时间过短必然会导致新生代的内存大小变小,垃圾回收频率变高,效率可能降低。
-XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器会自动调整年轻代Eden区大小和Survivor区大小的比例,以达成目标系统规定的最低响应时间或者收集频率等指标。此参数建议在使用并行收集器时,一直打开。
-XX:CGTIMERatio 吞吐量大小(0-100),默认为99。
4. CMS收集器
Concurrent Mark Sweep,采用标记-清除算法,用于老年代,常与ParNew协同工作。优点在于并发收集与低停顿。
注:并行是指同一时刻同时做多件事情,而并发是指同一时间间隔内做多件事情
初始标记
标记老年代中所有的GC Roots对象和年轻代中活着的对象引用到的老年代的对象,时间短;
并发标记
从“初始标记”阶段标记的对象开始找出所有存活的对象;
重新标记
用来处理前一个阶段因为引用关系改变导致没有标记到的存活对象,时间短;
并发清理
清除那些没有标记的对象并且回收空间。
缺点:占用大量的cpu资源、无法处理浮点垃圾、出现Concurrent MarkFailure、空间碎片。
-XX:+UseConcMarkSweepGC:即CMS收集,设置年老代为并发收集。CMS收集是JDK1.4后期版本开始引入的新GC算法。它的主要适合场景是对响应时间的重要性需求大于对吞吐量的需求,能够承受垃圾回收线程和应用线程共享CPU资源,并且应用中存在比较多的长生命周期对象。CMS收集的目标是尽量减少应用的暂停时间,减少Full GC发生的几率,利用和应用程序线程并发的垃圾回收线程来标记清除年老代内存。
-XX:+UseParNewGC:设置年轻代为并发收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此参数。
-XX:CMSFullGCsBeforeCompaction=0:由于并发收集器不对内存空间进行压缩和整理,所以运行一段时间并行收集以后会产生内存碎片,内存使用效率降低。此参数设置运行0次Full GC后对内存空间进行压缩和整理,即每次Full GC后立刻开始压缩和整理内存。
-XX:+UseCMSCompactAtFullCollection:打开内存空间的压缩和整理,在Full GC后执行。可能会影响性能,但可以消除内存碎片。
-XX:+CMSIncrementalMode:设置为增量收集模式。一般适用于单CPU情况。
-XX:CMSInitiatingOccupancyFraction=70:表示年老代内存空间使用到70%时就开始执行CMS收集,以确保年老代有足够的空间接纳来自年轻代的对象,避免Full GC的发生。
5. G1收集器
G1(Garbage First)垃圾收集器是当今垃圾回收技术最前沿的成果之一,早在JDK7就已加入JVM的收集器大家庭中,成为HotSpot重点发展的垃圾回收技术。
优势:并行(多核CPU)与并发;
分代收集(新生代和老年代区分不明显);
空间整合;
限制收集范围,可预测的停顿。
步骤:初始标记、并发标记、最终标记和筛选回收。
I global concurrent marking (全局并发标记)
II Initial marking phase:标记GC Root,STW
III Root region scanning phase:标记存活Region
IV Concurrent marking phase:标记存活的对象
V Remark phase :重新标记,STW
VI Cleanup phase:部分STW
-XX:+UseG1GC 开启G1
-XX:G1HeapRegionSize=n,region的大小,1-32M,2048个
-XX:MaxGCPauseMillis=200 最大停顿时间
-XX:G1NewSizePercent -XX:G1MaxNewSizePercent
-XX:G1ReservePercent=10 保留防止to space溢出()
-XX:ParallelGCThreads=n SWT线程数(停止应用程序)
-XX:ConcGCThreads=n 并发线程数=1/4*并行