1、基于jdk命令行工具的监控
1.1. jvm的参数类型
- 标准参数
-help -server -client -version -showversion -cp -classpath
- x参数(非标准化参数)
-Xint:解释执行
-Xcomp:第一次使用就编译成本地代码
-Ximxed:混合模式,jvm自己来决定是否执行成本地代码
- xx参数(非标准化参数,主要用于jvm调优和debug)
Boolean类型
格式:-XX:[+ -] 表示启用或禁用name属性
例如: -XX:+UserConcMarkSweepGC (启用cms垃圾回收器)
-XX:+UserG1GC(启用G1垃圾回收器)
非Boolean类型
格式:-XX:= 表示name属性的值是value
例如: -XX:MaxGCPauseMillis=500 (gc最大停顿时间是500毫秒)
-XX:GCTimeRatio=19
-Xmx -Xms(xx参数)
1.2. 运行时jvm参数查看
-XX:+PrintFlagsInitial 该命令可以查看所有JVM参数启动的初始值
-XX:+PrintFlagsFinal 查看最终值,初始值可能被修改掉
-XX:+UnlockExperimentalVMOptions 解锁实验性参数
-XX:+UnlockDiagnosticVMOptions 解锁诊断参数
-XX:+PrintCommandLineFlags 打印命令行参数
java -XX:+PrintFlagsFinal -version > flag.txt (如下图)
bool UseHeavyMonitors = false {product}
bool UseInlineCaches = true {product}
bool UseInterpreter = true {product}
bool UseJumpTables = true {C2 product}
bool UseLWPSynchronization = true {product}
bool UseLargePages = false {pd product}
bool UseLargePagesInMetaspace = false {product}
bool UseLargePagesIndividualAllocation := false {pd product}
bool UseLockedTracing = false {product}
bool UseLoopCounter = true {product}
bool UseLoopInvariantCodeMotion = true {C1 product}
bool UseLoopPredicate = true {C2 product}
bool UseMaximumCompactionOnSystemGC = true {product}
bool UseMembar = false {pd product}
bool UseNUMA = false {product}
bool UseNUMAInterleaving = false {product}
bool UseNewLongLShift = false {ARCH product}
bool UseOSErrorReporting = false {pd product}
bool UseOldInlining = true {C2 product}
bool UseOnStackReplacement = true {pd product}
bool UseOnlyInlinedBimorphic = true {C2 product}
bool UseOptoBiasInlining = true {C2 product}
bool UsePPCLWSYNC = true {product}
bool UsePSAdaptiveSurvivorSizePolicy = true {product}
bool UseParNewGC = false {product}
bool UseParallelGC := true {product}
【这些运行时参数对应的进程是执行 java -XX:+PrintFlagsFinal -version 的进程 bool UseG1GC = false
=表示默认值
:=表示被用户或JVM修改后的值】
jps (java提供的一个显示当前所有java进程pid的命令) jps -l
jinfo
jinfo -flag MaxHeapSize [pid] (查看最大内存)
jinfo -flags [pid]
jinfo -flag UseG1GC [pid] (查看垃圾回收器)
jinfo -flag UseParallelGC [pid] (查看垃圾回收器)
1.3. jstat查看虚拟机统计信息
- 查看类装载信息
jstat -class [pid] 1000 10 (每隔1000毫秒输出10次)
- 查看垃圾收集信息
jstat -gc [pid] 1000 10 (每隔1000毫秒输出10次)
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时
- 查看jit编译信息
jstat -compiler [pid]
1.4. jmap+mat实战内存溢出
- 演示内存溢出
- 如何导出内存映像文件
1、内存溢出自动导出(文件比较大,自动导出有可能导不出来)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
2、使用jmap命令手动导出
jmap -dump:format=b,file=heap.hprof [pid]
- 使用mat工具分析内存溢出
1.5.jstack实战死循环和死锁
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息
jstack [pid] > a.txt
实战死循环导致cpu飙高
top -p [pid] -H
jstack [pid]
printf "%x" 十进制线程的id
1.6.基于JVisualVM(jdk自带的)的可视化监控
- 监控本地tomacat
- 监控远程tomcat (修改Catalina.sh)
- 监控普通java应用进程
2、jvm层gc 调优
2.1.jvm的内存结构
程序计数器:存储的是当前线程执行的方法,如果不是native方法,它存储的就是当前线程正在执行的字节码指令的地址,如果是native方法,它保存的值是undefined。
虚拟机栈:它存储的是当前线程运行方法所需要的数据、指令、返回地址。
本地方法栈:虚拟机执行native方法服务
方法区:存储了每一个类的结构信息,例如运行时常量池、字段和方法数据、构造方法等。
堆:这块区域专门用于Java实例对象的内存分配
垃圾回收机制
判断是否垃圾
1、引用计数法:通过计算引用来判断是否为垃圾。
2、可达性分析算法:从gc root出发,所有可达的对象都是存活对象,不可达对象都是垃圾。
gcroot:类加载器、Thread、虚拟机栈的本地变量表(比如在java方法里面new出的一个对象,我们把它赋值给一个局部变量,在这个局部变量未销毁之前,这个new出点object就是gcroot)、static成员、常量引用、本地方法栈的变量、方法区常量引用的对象(例如在类里面定义了一个常量,如果该常量保存的是某个对象的地址,那么这个对象也是gcroot)等。
常用参数
-Xms
-Xmx
-XX:NewSize -XX:MaxNewSize
-XX:NewRatio -XX:SurvivorRatio
-XX:MetaspaceSize -XX:MaxMetaspaceSize
-XX:+UserCompressedClassPointers
-XX:CompressedClassSpaceSize
-XX:InitialCodeCacheSize
-XX:ReservedCodeCacheSize
2.2.垃圾回收算法
2.3.垃圾收集器
串行收集器Serial:Serial、Serial old
-XX:+UserSerialGC -XX:+UserSerialOldGC
并行收集器Parallel:Parallel Scavenge、Parallel old、吞吐量优先的收集器
-XX:+UserParallelGC -XX:+UserParallelOldGC
Server模式下默认的收集器
-XX:ParallerGCThreads= 开启多少个线程来垃圾回收
cpu>8 N=5/8
cpu<8 N=CPU
自适应特征,动态内存调整
并发收集器Concurrent:cms、g1 响应时间优先的收集器
CMS(老年代收集器): -XX:+UseConcMarkSweepGC(old区) -XX:+UseParNewGC(YOUND区)
缺点:cpu敏感、浮动垃圾、空间碎片
-XX:ConcGCThreads 并发的gc线程数
-XX:+UseCMSCompactAtFullCollection Fullgc之后压缩
-XX:CMSFullGCsBeforeCompaction 多少次Fullgc之后压缩一次
G1: -XX:+UseG1GC
停顿时间:垃圾收集器做垃圾回收中断应用执行的时间(-XX:MaxGCPauseMillis)
吞吐量:花在垃圾收集的时间和花在应用时间的占比。(-XX:GCTimeRatio=)垃圾收集时间占:1/1+n
最好的情况:再吞吐量最大的时候停顿时间最短。
现实情况:吞吐量最大的时候,停顿时间长。
如何选择垃圾收集器
- 优先调整堆的大小让服务器自己来选择
- 如果内存小于100M,使用串行收集器
- 如果是单核,并且没有停顿时间的要求,串行或者jvm自己选择
- 如果允许停顿时间超过1秒,选择并行或者jvm自己选择
- 如果响应时间特别重要,并且不能超过1秒,使用并发收集器