【深入理解JVM】详解GC日志参数配置及日志分析

2022-05-12 08:44:43 浏览数 (1)

一、首先模拟一个JVM堆内存不足的异常场景。

代码语言:javascript复制
public class GCTest {
    public static void main(String[] args) {
        List<Object> d = new ArrayList<Object>();
		while(true){
			d.add(new GCTest());
		}
    }
}

GCTest类的执行时,JVM参数配置:

代码语言:javascript复制
-Xms1m
-Xmx1m
-XX: PrintGCDetails
-XX: PrintGCTimeStamps
-XX: PrintGCDateStamps

执行后控制台输出如下图,准备下一步详细分析GC日志。

二、GC日志参数配置

1、堆空间参数

  • -Xms:初始堆大小 默认物理内存的1/64(小于1GB)空余堆大小小于40%时,JVM就会增大堆直到-Xmx的最大限制
  • -Xmx:最大堆大小 默认物理内存的1/4(小于1GB)空余堆大小大于70%时,JVM就会减少堆直到-Xms的最小限制
  • -Xmn:指定新生代的大小(Eden Survior from Survior to)的大小,增大新生代的大小,老年代的大小将被减小,sun 官方推荐 新生代的大小:堆 = 3 : 8
  • -XX:NewSize=512k:设置新生代大小
  • -XX:MaxNewSize=512k 设置新生代的最大值-Xmn 相当于设同时设置 NewSize=MaxNewSize
  • -XX:NewRation=4老年代:新生代 = 4:1,即 old:(Eden Survivor from Survivor to) ,则说明新生代为整个堆区的 1/5
  • -XX:SurvivorRation=8 设置 Eden 区和 Survivor。 默认值为8;即:Eden:Survivor=8:1 ==> Eden:Survivor from:Survivor to = 8:1:1 若值为3,即:Eden:Survivor=8:1 ==> Eden:Survivor from:Survivor to = 3:1:1
  • -XX: HeapDumpOnOutOfMemoryError:表示当JVM发生OOM时,自动生成DUMP文件。
  • -XX:HeapDumpPath:表示生成DUMP文件的路径,也可以指定文件名称。
  • -XX:MaxTenuringThreshold=15:设置将新生代对象转到老年代时需要经过多少次垃圾回收

2、元数据空间参数

  • -XX:PermSize:设置方法区大小(1.8以前的设置)
  • -XX:MaxPermSize: 设置方法区的最大值(1.8以前的设置) 1.8 之前可以理解为 永久区(PerSize,MaxPerSize)。 1.8 之后使用 元数据区 取代。(MaxMetaspaceSize)。
  • -XX:MaxMetaspaceSize=128k 来进行设置

3、栈空间参数

  • -Xss128k 栈内存的大小

4、Gc回收参数

  • -XX: PrintGC 输出GC日志
  • -XX: PrintGCDetails 输出GC的详细日志
  • -XX: PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
  • -XX: PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2018-06-19T21:53:59.230 0800)
  • -XX: PrintHeapAtGC 在进行GC的前后打印出堆的信息
  • -Xloggc:…/logs/gc.log 日志文件的输出路径

5、垃圾收集器参数

参数

描述

UseSerialGC

虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial Serial Old的收集器组合进行内存回收

UseParNewGC

打开此开关后,使用ParNew Serial Old的收集器组合进行内存回收

UseConcMarkSweepGC

打开此开关后,使用ParNew CMS Serial Old的收集器组合进行内存回收。Serial Old收集器将作为CMS收集器出现Concurrent Mode Failure失败后的后备收集器使用

UseParallelGC

虚拟机运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge Serial Old (PS Mark Sweep)的收集器组合进行内存回收

UserParallelOldGC

打开此开关后,使用Parallel Scavenge Parallel Old的收集器组合进行内存回收

SurvivorRatio

新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden: Survivor = 8:1

PretenureSizeThreshold

直接晋升到老年代的对象大小,设置这个参数后,大于这个参数的对象将直接在老年代分配

MaxTenuringThreshold

晋升到老年代的对象年龄。每个对象在坚持过一次Minor GC之后,年龄就增加1,当超过这个参数值时就进入老年代

UseAdaptiveSizePolicy

动态调整Java堆中各个区域的大小以及进入老年代的年龄

HandlePromotionFailure

是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况

ParallelGCThreads

设置并行GC时进行内存回收的线程数

GCTimeRatio

GC时间占总时间的比率,默认值是99, 即允许1%的GC时间。仅在使用Parallel Scavenge收集器时生效

MaxGCPauseMillis

设置GC的最大停顿时间。仅在使用Parallel Scavenge收集器时生效

CMSInitiatingOccupancyFraction

设置CMS收集器在老年代时间被使用多少后触发垃圾收集。默认值为68%,仅在使用CMS收集器时生效

UseCMSCompactAtFullCollection

设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片整理。仅在使用CMS收集器时生效

CMSFullGCsBeforeCompaction

设置CMS收集器在进行若干次垃圾收集后再启动一次内存碎片整理,仅在使用CMS收集器时生效

6、并行收集器设置

  • -XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
  • -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
  • -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1 n)

7 、并发收集器设置

  • -XX: CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
  • -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

三、解读GC日志

2019-07-31T01:49:29.633 0800: 0.086: [GC (Allocation Failure) [PSYoungGen: 504K->488K(1024K)] 504K->504K(1536K), 0.0007589 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

1、2019-07-31T01:49:29.633 0800:GC事件(GC event)开始的时间点 2、0.086:GC事件的开始时间,相对于JVM的启动时间,单位是秒(Measured in seconds) 3、GC :有两种:GC(Minor GC)和 Full GC . 4、Allocation Failure :引起垃圾回收的原因 5、PSYoungGen:新生代情况 6、504K->488K(1024K) :年轻代垃圾回收前的大小 -> 年轻代垃圾回收以后的大小(年轻代的总大小) 7、504K->504K(1536K) 0.0007589 secs:整个堆回收前的大小->整个堆回收后的大小(堆总大小), 回收时间 8、[Times: user=0.00 sys=0.00, real=0.00 secs] :Young GC用户耗时、Young GC用户耗时、Young GC实际耗时

常用的GC日志监控工具:jvisualvm、jconsole,这两个都是jdk自带的,在bin目录下。

0 人点赞