jvm监控排查问题相关工具:
jps、jstat、jinfo、jhat、jstack、jconsole、jmap、MAT、Btrace、psi_probe监控tomcat,通过gceasy查看和GCViewer查看GC,从而解决问题。
jps:查看所有的java进程
jps -help #显示jps所有的命令参数信息
jps #查看有哪些运行的java线程
jps -l #输出主类的全名
jps -v #输出虚拟机启动时的jvm参数
jps -m #输出传递给java进程main()函数的参数
jstat
监视虚拟机各种运行状态信息:主要是查看类加载、垃圾回收、JIT编译、新生代、老年代等
jstat -help #显示jsta命令所有的参数信息
jstat -class vmid #显示ClassLoader的相关信息
jstat -compiler vmid #显示JIT编译的相关信息
jstat -gc vmid #显示与GC相关的堆信息
jstat -gcnew vmid #显示新生代信息
jstat -gcold vmid #显示老年代信息
jstat -gcnewcapcacity vmid #显示新生代大小和使用情况
jstat -gcoldcapcacity vmid #显示老年代大小和使用情况
jstat -gcutil vmid #显示垃圾收集信息
#当然也可以在里面加上时间和次数,以上如果不加时间和次数,默认打印一次,如:
jstat -class vmid 时间 次数
jstat -gc vmid 时间 次数
jinfo
实时查看和调整虚拟机各项参数
jinfo -help #产看jinfo的相关命令参数信息
jinfo -flag MaxHeapSize vmid #查看最大堆内存的大小
jinfo -flag UseConcMarkSweepGC vmid #查看垃圾回收器
jinfo -flag UserG1GC vmid #查看垃圾回收器
jinfo -flag +PrintGC vmid #开启查看GC打印日志信息,默认关闭
jhat
分析heapdump文件,在浏览器上查看分析结果
jhat -help #查看jhat所有命令参数信息
jhat C:\Users\Administrator\Desktop\jvm\heap.hprof
jstack
生成虚拟机当前时刻的线程快照,可以进行日志分析,定位线上问题。
死锁:A线程和B线程相互获取资源,都在等待对方,导致死锁
public class DeadLockDemo {
private static Object resource1 = new Object();//资源 1
private static Object resource2 = new Object();//资源 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "线程 2").start();
}
}
由于两者之间相互等待,所以运行时间很长,程序没有结果,因此可以通过查看进程jps拿到程序的进程信息,从而通过jstack 进程id,从而获取详细的日志信息。
jdk可视化工具分析:jconsole,内存监控和线程监控
可进行远程监控,方便线上排查问题
如果需要使用 JConsole 连接远程进程,可以在远程 Java 程序启动时的配置文件上加上下面这些参数:
-Djava.rmi.server.hostname=外网访问 ip 地址
-Dcom.sun.management.jmxremote.port=60001 //监控的端口号
-Dcom.sun.management.jmxremote.authenticate=false //关闭认证
-Dcom.sun.management.jmxremote.ssl=false
在使用 JConsole 连接时,远程进程地址如下:
外网访问 ip 地址:60001
连接好就可以查看监控信息了
jmap:生成堆转储快照
jps -l #拿到pid信息
jmap -dump:format=b,file=heap.hprof pid #b表示二进制,生成文件heap.prof
jmap -heap pid #内存区块信息
此时可以配合MAT分析内存溢出的信息,导入映像文件,进行查看。
java线程的状态:
NEW:线程还没开始
WAITING:等待状态
RUNNABLE:运行状态
TIMED_WAITING:限时等待
BLOCKING:阻塞等待状态
TERMINATED:终止退出
基于jvisualvm的可视化监控
监控本地tomcat、监控远程tomcat、监控普通java进程等都可以。
监控远程tomcat,需要修改tomcat的配置文件catalina.sh添加如下信息:
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.anthenticate=false -Dcom.sun.management.jmxremote.jmxremote.ssl=false -Djava.net.preferIPV4Stack=true -Djava.rmi.server.hostname=10.19.10.10"
添加完连接信息之后,就可以进行jmx连接了。
监控远程tomcat
基于Btrace的监控调试,Btrace可以动态地向母亲应用程序的字节码注入跟踪代码。
javaComplierApi:JVMTI、Agent、Instrumentation+ASM
Btrace安装:
新建环境变量,添加path.,类似eclipse。
两种运行脚本方式:在jvisualvm添加Btrace插件,添加classpath,类似配置jconsole.
使用命令行btrace <trace_script>
三个jar包引入pom文件:Btrace-agent.jar、Btrace-boot.jar、Btrace-client.jar
@Btrace注解:
@OnMethod(clazz="com.study.mt.testController",
method="arg1",
localtion=@Localtion(kind.ENTRY))
命令:
jps -l
btrace pid printArgSimple.java
可以采用命令启动,也可以在jvisualvm中使用
Btrace使用:
拦截方法:
普通方法,@OnMethod(clazz=" ",method=" ")
构造方法:@OnMethod(clazz="",method="<init>")
拦截同名函数,用参数区分
拦截时机:入口、运行、结束等
kind.Entry:入口,默认值
kinf.RETURN:返回
kind.THROW:异常
kind.LINE=行
异常吞掉也没关系,BTrace也可以追踪,方便排查问题
BTrace只能本地运行,如果需要远程连接,则需要修改源代码
拦截this、参数、返回值:
this:@self
入参:可以用AnyType,也可以用真实类型,同名的用真实的
返回值:@return
其他:获取对象的值
简单类型:直接获取
复杂类型:发射、类名+属性名
注意:生产环境下使用,需要注意被修改的字节码不会被还原
tomcat性能调优:首先需要修改tomcat的配置文件:tocat-user.xml、添加manager.xml:
tocat-user.xml添加几个角色信息:
<role rolename="tomcat"/>
<role rolename="manager-status"/>
<role rolename="manager-gui"/>
<role username="tomcat" password="tomcat"
roles="tomcat,managet-status,managet-gui"/>
manager.xml配置如下信息:
<context provileged="true" antiResourceLock="false"
docBase='${catalina.home}/webapps/manager'>
<Valve className=
"org.apache.catalina.valves.RemoteAddrValve"
allow="^192.168.*$" />
</Context>
访问远程tomcat的管理页面,可以在server.status中查看到jvm参数信息。
除了使用tomcat的管理页面看到tomcat的jvm信息之外,还可以通过psi_probe监控看到相关参数信息,需要配置tomcat-user.xml和manager.xml的配置,放入到tomcat下面即可。