Java启动通用参数,自动记录GC等信息到专门日志文件中
为了分析Java(或者说JVM)的运行情况,以及遇到OOM等问题是可以有日志文件便于定位问题,建议所有Java启动时都开启GC记录到专门的日志文件中。
由于Java1.8 和 Java11或更高版本命令参数不同,下面写了一个适合Linux的通用的Shell脚本,供启动参考:
#获取当前Java版本号,然后提取主版本号、提取次版本号(如果存在)
java_ver=$(java -version 2>&1 | head -n 1 | awk -F[\"\.] '{print $2"."$3}')
major_ver=$(echo $java_ver | awk -F. '{print $1}')
minor_ver=$(echo $java_ver | awk -F. '{print $2}')
# 判断当前Java版本,Java11或更高的GC参数 与 Java1.8的GC参数不同
if [ $major_ver -ge 11 ]; thenGC_FLAGS="-XX:+UseG1GC -XX:MaxGCPauseMillis=500 -Xlog:gc*,os*:gclogs/jvm_gc_StartUpTime%t.log:time,uptime,level,tags:filecount=100,filesize=20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=gclogs"
elif [[ $major_ver -eq 1 && $minor_ver -ge 8 ]]; thenGC_FLAGS="-XX:+UseParallelGC -XX:MaxGCPauseMillis=500 -verbose:gc -Xloggc:gclogs/jvm_gc_StartUpTime%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=100 -XX:GCLogFileSize=20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=gclogs -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCDetails"
else echo "java version不满足要求,当前java版本:$java_ver" exit -5
fi
JVM_OPTIONS="${JVM_OPTIONS} ${GC_FLAGS} -Dfile.encoding=utf8 -Dsun.jnu.encoding=utf8 " ----(后面将$JVM_OPTIONS变量放到java启动参数中即可, 具体省略) ----
以上脚本备注说明:
- 通过获取当前Java版本号,对Java11和Java1.8分别采用不同的启动参数。
- UseG1GC表示:(仅适合Java11或更高版本)启用G1垃圾收集器。
- UseParallelGC表示:(适合Java1.8)新生代使用ParallelScanvenge回收,老年代使用Serial Old回收。
- MaxGCPauseMillis告诉GC,GC回收时的期望最大值停顿时长
- HeapDumpOnOutOfMemoryError和HeapDumpPath,告诉GC,当发生OutOfMemory时,需把当时的内存等信息输出到指定目录,便于后续定位详细分析。
- 对于Java11或更高版本,通过-Xlog记录JVM运行的各类信息。可通过命令java -Xlog:help参考具体的帮助信息,简要说明如下:
对于Java11或更高版本,JVM自身内置了有几十种信息,且每条信息自动带有一个tag或者多个tag,通过以下命令指定输出匹配的tag及输出形式。
命令格式:-Xlog[:[selections][:[output][:[decorators][:output-options]]]]
- selections
指定通过哪些tag来过滤信息。多个tag之间采用逗号分割。(注意加号、逗号、星号分别代表不同的含义),示例:
all 匹配包含所有标签(不建议正式使用,仅适合用于研究观察每种具体消息是什么内容,带什么tag)
gc 匹配等于gc标签的信息。若某个信息带gc标签的同时还带有其他标签则无法匹配,不会输出。
gc* 匹配包含gc的标签。若某个信息带gc标签的同时还带有其他标签则可以匹配,会输出。
gc+thread 匹配同时等于gc和thread的信息。若某个信息只带有gc标签则无法匹配,不输出。若某个信息只带有thread标签则无法匹配,不输出。若某个信息带gc标签和thread标签的同时还带有其他标签则无法匹配,不会输出。若某个信息同时带gc标签和thread标签且无其他标签则匹配,会输出。
gc,thread 匹配等于gc或者匹配等于thread的信息。若某个信息只带有gc标签则匹配,输出。若某个信息只带有thread标签则匹配,输出。若某个信息带gc标签和thread标签的同时还带有其他标签则无法匹配,不会输出。
gc*,thread* 匹配包含gc或者匹配包含thread的信息。若某个信息只带有gc标签则匹配,输出。若某个信息只带有thread标签则匹配,输出。若某个信息带gc标签和thread标签的同时还带有其他标签则匹配,输出。
还可以通过等号对每种标签指定输出的级别。
- output
指定输出的目标位置:可以为stdout、stderr、指定文件名。
- decorators
指定输出内容的格式。格式符号如下:
time:当前时间,当前时区时间,如:[2020-04-02T16:17:54.614+0800]
utctime:通用时间,0时区时间,如:[2020-04-02T08:17:54.614+0000]
timemills:System.currentTimeMillis()的数值,如:[1585815474614ms]
timenanos:System.nanoTime()的数值,如:[108171620762600ns]
uptime:虚拟机启动到当前时间间隔,如:[0.179s]
uptimemillis:虚拟机启动经过的毫秒数,如:[171ms]
uptimenanos:虚拟机启动到当前经过的时间,纳秒,如:[108303677015300ns]
hostname:主机名
pid:进程id
tid:线程id
level:日志级别
tags:标签名
- output-options
指定输出控制选项,比如foldmultilines是否折行、filesize日志滚动切换大小、filecount日志滚动是保持的文件个数(0表示不滚动)。
以上配置后,生成的gc日志文件内容如下:
[2024-11-29T17:51:38.794+0800][6.288s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47651588044544, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:38.794+0800][6.288s][info][os,thread ] Thread is alive (tid: 58179, pthread id: 47651588044544).
[2024-11-29T17:51:38.848+0800][6.342s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47651787933440, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:38.848+0800][6.342s][info][os,thread ] Thread is alive (tid: 58180, pthread id: 47651787933440).
[2024-11-29T17:51:39.232+0800][6.726s][info][os,thread ] JavaThread exiting (tid: 58148).
[2024-11-29T17:51:39.232+0800][6.726s][info][os,thread ] Thread finished (tid: 58148, pthread id: 47651539126016).
[2024-11-29T17:51:39.380+0800][6.874s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47651539126016, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:39.380+0800][6.874s][info][os,thread ] Thread is alive (tid: 58185, pthread id: 47651539126016).
[2024-11-29T17:51:39.464+0800][6.958s][info][gc,start ] GC(4) Pause Young (Metadata GC Threshold)
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,heap ] GC(4) PSYoungGen: 279051K(917504K)->10619K(917504K) Eden: 279051K(786432K)->0K(786432K) From: 0K(131072K)->10619K(131072K)
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,heap ] GC(4) ParOldGen: 20412K(2097152K)->20484K(2097152K)
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,metaspace ] GC(4) Metaspace: 59150K(59776K)->59150K(59776K) NonClass: 51854K(52160K)->51854K(52160K) Class: 7296K(7616K)->7296K(7616K)
[2024-11-29T17:51:39.474+0800][6.968s][info][gc ] GC(4) Pause Young (Metadata GC Threshold) 292M->30M(2944M) 9.717ms
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,cpu ] GC(4) User=0.04s Sys=0.00s Real=0.01s
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,start ] GC(5) Pause Full (Metadata GC Threshold)
[2024-11-29T17:51:39.474+0800][6.968s][info][gc,phases,start] GC(5) Marking Phase
[2024-11-29T17:51:39.511+0800][7.005s][info][gc,phases ] GC(5) Marking Phase 36.589ms
[2024-11-29T17:51:39.511+0800][7.005s][info][gc,phases,start] GC(5) Summary Phase
[2024-11-29T17:51:39.511+0800][7.005s][info][gc,phases ] GC(5) Summary Phase 0.007ms
[2024-11-29T17:51:39.511+0800][7.005s][info][gc,phases,start] GC(5) Adjust Roots
[2024-11-29T17:51:39.517+0800][7.011s][info][gc,phases ] GC(5) Adjust Roots 6.570ms
[2024-11-29T17:51:39.517+0800][7.011s][info][gc,phases,start] GC(5) Compaction Phase
[2024-11-29T17:51:39.542+0800][7.036s][info][gc,phases ] GC(5) Compaction Phase 24.330ms
[2024-11-29T17:51:39.542+0800][7.036s][info][gc,phases,start] GC(5) Post Compact
[2024-11-29T17:51:39.543+0800][7.037s][info][gc,phases ] GC(5) Post Compact 1.144ms
[2024-11-29T17:51:39.543+0800][7.037s][info][gc,heap ] GC(5) PSYoungGen: 10619K(917504K)->0K(917504K) Eden: 0K(786432K)->0K(786432K) From: 10619K(131072K)->0K(131072K)
[2024-11-29T17:51:39.543+0800][7.037s][info][gc,heap ] GC(5) ParOldGen: 20484K(2097152K)->30098K(2097152K)
[2024-11-29T17:51:39.543+0800][7.037s][info][gc,metaspace ] GC(5) Metaspace: 59150K(59776K)->59132K(59776K) NonClass: 51854K(52160K)->51841K(52160K) Class: 7296K(7616K)->7290K(7616K)
[2024-11-29T17:51:39.543+0800][7.037s][info][gc ] GC(5) Pause Full (Metadata GC Threshold) 30M->29M(2944M) 68.910ms
[2024-11-29T17:51:39.543+0800][7.037s][info][gc,cpu ] GC(5) User=0.25s Sys=0.04s Real=0.07s
[2024-11-29T17:51:39.663+0800][7.156s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47651788986112, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:39.663+0800][7.157s][info][os,thread ] Thread is alive (tid: 58186, pthread id: 47651788986112).
[2024-11-29T17:51:39.767+0800][7.261s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47654009575168, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:39.767+0800][7.261s][info][os,thread ] Thread is alive (tid: 58187, pthread id: 47654009575168).
[2024-11-29T17:51:39.999+0800][7.493s][info][os ] attempting shared library load of /usr/lib/jdk/jdk-21.0.2/lib/libawt.so
[2024-11-29T17:51:40.000+0800][7.494s][info][os ] shared library load of /usr/lib/jdk/jdk-21.0.2/lib/libawt.so was successful
[2024-11-29T17:51:40.001+0800][7.495s][info][os ] attempting shared library load of /usr/lib/jdk/jdk-21.0.2/lib/libawt_headless.so
[2024-11-29T17:51:40.002+0800][7.496s][info][os ] shared library load of /usr/lib/jdk/jdk-21.0.2/lib/libawt_headless.so was successful
[2024-11-29T17:51:42.535+0800][10.029s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47654010627840, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:42.536+0800][10.030s][info][os,thread ] Thread is alive (tid: 58194, pthread id: 47654010627840).
[2024-11-29T17:51:42.548+0800][10.042s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47654011680512, attributes: stacksize: 1024k, guardsize: 4k, detached).
[2024-11-29T17:51:42.548+0800][10.042s][info][os,thread ] Thread is alive (tid: 58195, pthread id: 47654011680512).
[2024-11-29T17:51:42.548+0800][10.042s][info][os,thread ] Thread "Unknown thread" started (pthread id: 47654012733184, attributes: stacksize: 1024k, guardsize: 4k, detached).