-XX:+UseSerialGC
[GC (Allocation Failure) [DefNew: 494K->28K(1856K), 0.0007607 secs][Tenured: 2460K->2088K(4096K), 0.0185495 secs] 2891K->2088K(5952K), [Metaspace: 8175K->8175K(1056768K)], 0.0199235 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[Full GC (Allocation Failure) [Tenured: 2088K->1865K(13696K), 0.0050507 secs] 2088K->1865K(15616K), [Metaspace: 8175K->8175K(1056768K)], 0.0051147 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
- ParNew收集器
1.-XX:+UseParNewGC
2. 新生代并行,老年代串行
-XX:ParallelGCThreads
限制线程数量,最好与电脑的核数相等[GC (Allocation Failure) [ParNew: 534K->80K(1856K), 0.0005378 secs][Tenured: 2991K->2404K(4096K), 0.0255715 secs] 3445K->2404K(5952K), [Metaspace: 8167K->8167K(1056768K)], 0.0264774 secs] [Times: user=0.02 sys=0.00, real=0.03 secs]
[Full GC (Allocation Failure) [Tenured: 2404K->2104K(13696K), 0.0092037 secs] 2404K->2104K(15616K), [Metaspace: 8167K->8167K(1056768K)], 0.0092783 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Parallel收集器
-XX:+UseParallelGC
使用Parallel收集器+ 老年代串行-XX:+UseParallelOldGC
使用Parallel收集器+ 并行老年代[GC (Allocation Failure) [PSYoungGen: 384K->0K(5120K)] 3243K->2954K(18944K), 0.0005837 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(5120K)] [ParOldGen: 2954K->2015K(4096K)] 2954K->2015K(9216K), [Metaspace: 8165K->8165K(1056768K)], 0.0346569 secs] [Times: user=0.19 sys=0.00, real=0.03 secs]
-XX:MaxGCPauseMills
-XX:GCTimeRatio
- CMS收集器(Concurrent Mark Sweep 并发标记清除)
-XX:+UseConcMarkSweepGC
使用并发标记清除收集器
3. 如上图所示,CMS运行过程比较复杂,着重实现了标记的过程,可分为
1. 初始标记
1. 根可以直接关联到的对象
2. 速度快
2. 并发标记(和用户线程一起)
1. 主要标记过程,标记全部对象
3. 重新标记
1. 由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
4. 并发清除(和用户线程一起)
1. 基于标记结果,直接清理对象
[GC (CMS Initial Mark) [1 CMS-initial-mark: 2125K(4096K)] 2362K(5952K), 0.0013094 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Final Remark) [YG occupancy: 517 K (1856 K)][Rescan (parallel) , 0.0007277 secs][weak refs processing, 0.0000171 secs][class unloading, 0.0006060 secs][scrub symbol table, 0.0005643 secs][scrub string table, 0.0001149 secs][1 CMS-remark: 2125K(4096K)] 2643K(5952K), 0.0020999 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
-XX:CMSInitiatingOccupancyFraction
设置触发GC的阈值-XX:+ UseCMSCompactAtFullCollection
Full GC后,进行一次整,整理过程是独占的,会引起停顿时间变长-XX:+CMSFullGCsBeforeCompaction
设置进行几次Full GC后,进行一次碎片整理-XX:ParallelCMSThreads
设定CMS的线程数量,线程不是越多越快,需要按需设计,最好和电脑的核数一致-XX:+UseSerialGC:在新生代和老年代使用串行收集器
-XX:SurvivorRatio:设置eden区大小和survivior区大小的比例
-XX:NewRatio:新生代和老年代的比
-XX:+UseParNewGC:在新生代使用并行收集器
-XX:+UseParallelGC :新生代使用并行回收收集器
-XX:+UseParallelOldGC:老年代使用并行回收收集器
-XX:ParallelGCThreads:设置用于垃圾回收的线程数
-XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
-XX:ParallelCMSThreads:设定CMS的线程数量
-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发
-XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理
-XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩
-XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收
-XX:CMSInitiatingPermOccupancyFraction:当永久区占用率达到这一百分比时,启动CMS回收
-XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收
为减轻GC压力,我们需要注意些什么?
- 软件架构设计
- 代码编写
- 堆空间合理分配
- JDK的选择(升级JDK可能会带来额外的性能提升)