JVM调优(一)——参数查询和问题排查
JVM的参数类型
标准参数
说明:每个版本的jdk中,一般不会变动
- -help
- -server -client
- -version -showversion
- -cp -classpath
X参数
说明:每个版本的jdk中,可能会发生变动
- -Xint: 解释执行
- -Xcomp:第一次使用就编译成本地代码
- -Xmixed:混合模式,JVM自己来决定是否编译成本地代码
XX参数
特点
- 非标准化参数
- 相对不稳定
- 主要用于JVM调优和Debug
分类
-
Boolean类型
格式:-XX:[+-]<name>表示启用或禁用name属性 比如: -XX:+UseConcMarkSweepGC -XX:+UseG1GC
-
非Boolean类型
格式:-XX:<name>=<value> 表示name属性的值是value 比如: -XX:MaxGCPauseMilis=500 XX:GCTimeRatio=19
示例
- -Xms等价于-XX:InitialHeapSize //初始化的堆大小
- -Xmx等价于-XX:MaxHeapSize //最大堆大小
运行时JVM参数查看
-XX:+PrintFlagsInitial //查看初始值
-XX:+PrintFlagsFinal //查看最终的值
-XX:+UnlockExperimentalVMOptions //解锁实验参数
-XX:+UnlockDiagnosticVMOptions //解锁诊断参数
-XX:+PrintCommandLineFlags //打印命令行参数
PrintFlagsFinal
=表示默认值
:=被用户或者JVM修改后的值
jps
查看java进程,类似Linux 中的ps
jinfo
jinfo -flag MaxHeapSize xxxx(进程号) //查看最大堆内存
jinfo -flag UseConcMarkSweepGC xxx(进程号) //查看是否使用了这个GC
jinfo -flag UseG1GC xxx(进程号) //是否使用了G1回收器
jinfo -flag UseParallelGC xxx(进程号) //是否使用了并行回收器
jstat查看虚拟机统计信息
命令格式:
options:-class,-compiler,-gc,-printcompilation
类装载
查看类加载信息:
jstat -class xxx(进程号)
说明:
3176(进程号)
1000(1000毫秒,没隔1秒)
10(一共输出10次)
3176这个进程,没隔1s输出一次,一共输出10次
垃圾收集
-gc/-gcutil/-gccause/-gcnew/-gccold
-gc输出结果
S0C/S1C/S0U/S1U:S0和S1的总量与使用量
EC/EU:Eden区总量和使用量
OC/OU:Old区总量与使用量
MC/MU:Metaspace区总量与使用量
CCSC/CCSU:压缩类空间总量与使用量
YGC/YGCT:youngGC的次数与时间
FGC/FGCT:FullGC的次数与时间
GCT:总的GC时间
使用
jstat -gc xxx(进程号) 1000 10 //动态输出,没隔1s输出一次,一共输出10次
JIT编译
查看JIT编译信息
jstat -compiler PID
jstat -printcompilation PID
jmap+MAT实战内存溢出
jvm内存结构
如何导出内存映像文件
内存溢出自动导出
设置两个参数:
-XX:+HeapDumpOnOutOfMemoryError //开启功能
-XX:HeapDumpPath=./ //导出到什么路径
使用jmap命令手动导出
jmap -dump:format=b,file=help.hprof
format=b 导出的格式是二进制的文件
MAT分析内存溢出
- 下载MAT工具
- 将导出的映像文件导入到MAT中,进行分析
jstack实战死循环与死锁
线程的状态:
1、new
2、running
3、blocked
4、waiting
5、timed_waiting
6、terminated
实战死循环导致cpu飙高
- 查看cpu负载:
top //查看laod average,发现cpu非常高;
- 在top列表里找到cpu占用高的进程
- 通过jstack PID > xxx.txt ,通过jstack将该进程的信息打印到xxx.txt的文件中
- 对进程内部的线程所占用资源情况进行分析:
top -p PID -H #查看某个进程内部线程占用情况
发现有5个线程占用的cpu非常高:
- 将上图分析出来的PID(十进制)转换成十进制:
printf "%x" 8247
2037
-
在之前步骤里导出的jstack信息的文件中,搜索上个步骤转换出来的十六进制PID
0x2037 表示一个十六进制的数:2037
搜索出来之后,就能够看到该线程的堆栈信息了
实战死锁导致cpu飙高
-
查看项目进程号
ps -ef | grep tomcat
-
通过jstack PID > xxx.txt ,通过jstack将该进程的信息打印到xxx.txt的文件中
-
拉取到文末
该分析工具能准确的找到项目中存在的的死锁和位置