tools ref
- 2-1
java -version
java -Xint -version
ps -ef | grep tomcat
jinfo -flag MaxHeapSize 74691
jinfo -flag ThreadStackSize 74691 # -xss
- 2-2
java -XX:+PrintFlagsFinal -version #约700多个参数
jps -l
58274 sun.tools.jps.Jps
74691 org.apache.catalina.startup.Bootstrap
jinfo -flag MaxHeapSize 74691
-XX:MaxHeapSize=2147483648
jinfo -flags 74691 #手动赋值过或脚本设置过的参数
Non-default VM flags: -XX:CICompilerCount=3 ...
jinfo -flag UseConcMarkSweepGC 74691 #is enabled cms
-XX:-UseConcMarkSweepGC
jinfo -flag UseG1GC 74691
-XX:-UseG1GC
jinfo -flag UseParallelGC 74691
-XX:+UseParallelGC
- 2-3
jstat -class 74691
Loaded Bytes Unloaded Bytes Time
3669 7848.4 0 0.0 3.66
jstat -gc 74691
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
11776.0 12800.0 2652.1 0.0 29184.0 17214.6 65536.0 15089.2 25856.0 25214.5 2816.0 2624.6 12 0.091 1 0.053 0.144
jstat -gc 74691 1000 10 #每秒1次 10次
jstat -compiler 74691
Compiled Failed Invalid Time FailedType FailedMethod
2704 1 0 6.97 1 org/apache/tomcat/util/IntrospectionUtils setProperty
- 2-4
- jdk8 Metaspace 调优
# 堆溢出
死循环:生成用户对象,加入list中
运行vm参数`-Xms32M -Xmx32M`
Exception in thread "http-nio-8080-exec-3" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "Catalina-utility-2" java.lang.OutOfMemoryError: GC overhead limit exceeded
---
# 非堆溢出
死循环:依赖`asm core`动态生成Class,加入list中
运行vm参数`-XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M`
Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: Metaspace
- 2-5 导出内存映像文件
-
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./
jmap -dump:format=b,file=heap.hprof 5566
-
#自动导出
运行vm参数 `-Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./`
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to ./java_pid1948.hprof ...
Heap dump file created [44124222 bytes in 0.346 secs]
Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
#手动导出
jmap -help
jps -l
5566 com.asvgo.monitor_tuning.MonitorTuningApplication
cd ~/hprof
jmap -dump:format=b,file=heap.hprof 5566
Dumping heap to /Users/xianfan/hprof/heap.hprof ...
Heap dump file created
jmap -heap 5566 #每一区块占用内存情况
- 2-6 MAT分析内存溢出
# 下载安装 Eclipse Memory Analyzer
# 文件打开之前的.hprof文件分析
1. 查看对象数量
`正则表达式筛选包名`
`右键 - Merge shortest Path to GC Roots - exclude all phantom/weak/soft etc. references 排除弱引用`
2. 查看对象占用字节数
2-7 jstack与线程的状态
jps -l
jstack 33143 > 33143.txt `包含每个线程的信息,包括线程池,GC等`
top -pid 33143 -h
2-8 jstack实战死循环与死锁 cpu飙高问题
- 多么痛的领悟
`死循环`
写死循环程序 CpuController#loop
多个浏览器窗口访问loop
top查看 `load average:`
jstack 7930 > 7930.txt
top -p 7930 -H
printf "%x" 8247 `转十六进制`
2037
`死锁`
写死锁程序 CpuController#deadlock
ps -ef | grep java `找到程序进程id`
jstack 23674 > 23674.txt
定位到`Found 1 deadlock.`
- 3-1 监控本地java进程
jvisualvm
$JAVA_HOME/bin/jvisualvm
工具-->配置插件中心: https://visualvm.github.io/pluginscenters.html
安装插件`visualGC`
- 3-2 监控远程的java进程
jvisualvm+JMX连接
远程-->添加远程主机
修改tomcat/bin/Catalina.sh
JAVA_OPTS="JAVA_OPTS
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9004
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.sll=false
-Djava.net.preferIPv4Stack=true
-Djava.rmi.server.hostname=10.120.3.6`
"
./bin/startup.sh `重启`
tail -f ./logs/catalina.out
`client` 在主机上右键-->添加JMX连接,设置端口9004
---
监控远程普通应用进程
`启动应用 ->` nohup java -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9005
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.sll=false
-Djava.net.preferIPv4Stack=true
-Djava.rmi.server.hostname=10.120.3.6 -jar monitor_tuning.jar
tail -f nohup.out
`client` 在主机上右键-->添加JMX连接,设置端口9005
4-1 btrace入门
在不修改程序的前提下,动态获取某个类的某个方法的参数,不局限于controller
只能在本机执行
github: https://github.com/btraceio/btrace
设置环境变量 BTRACE_HOME
两种运行脚本方式:
1. 使用命令行btrace
2. 在JVisualVM中添加 `Btrace Workbench` 插件,添加classpath
btrace能力:
在不修改程序的前提下,动态获取某个类的某个方法的参数,不局限于controller
#1
编写脚本 `PrintArgSimple.java`
jps -l
btrace 13348 PrintArgSimple.java
#2
在JVisualVM的进程菜单上右键-->Trace application-->手动编写btrace脚本
- 4-2 拦截构造函数、同名函数
如何拦截构造函数
编写代码Ch4Controller#constructor
编写btrace脚本PrintConstructor.java
如何拦截同名函数
编写代码Ch4Controller
编写btrace脚本PrintSame.java
- 4-3 拦截返回值、异常、行号
编写btrace脚本PrintReturn.java
编写异常源码ch4#exception 、 脚本PrintOnThrow
编写脚本PrintLine,判断某行是否执行了
- 4-4 拦截复杂参数、坏境变量、正则匹配拦截
获取对象值
简单类型:直接获取
复杂类型:反射,类名+属性名
编写源码ch4#arg2 、 编写脚本PrintArgComplex
jps -l
btrace PrintArgComplex.java
抛错,找不到User类
btrace -cp "User的class文件所在目录" PrintArgComplex.java
编写正则表达式脚本 PrintRegex.java
method="/.*/" 表示匹配任意方法
编写脚本 PrintJInfo.java 打印环境变量
类似 jinfo -sysprops
- 4-5 注意事项
默认只能本地运行
生产环境下可以使用,但被修改的字节码不会被还原
- 5-1 tomcat远程debug
jdwp
rz
sz
- 5-2 tomcat-manager监控
- 5-3 psi-probe监控