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-classvmid#显示ClassLoader的相关信息jstat-compilervmid#显示JIT编译的相关信息jstat-gcvmid#显示与GC相关的堆信息jstat-gcnewvmid#显示新生代信息jstat-gcoldvmid#显示老年代信息jstat-gcnewcapcacityvmid#显示新生代大小使用情况jstat-gcoldcapcacityvmid#显示老年代大小使用情况jstat-gcutilvmid#显示垃圾收集信息#当然也可以在里面加上时间和次数,以上如果不加时间和次数,默认打印一次,如:jstat-classvmid时间次数jstat-gcvmid时间次数
jinfo:实时查看和调整虚拟机各项参数
jinfo-help#产看jinfo的相关命令参数信息jinfo-flagMaxHeapSizevmid#查看最大堆内存的大小jinfo-flagUseConcMarkSweepGCvmid#查看垃圾回收器jinfo-flagUserG1GCvmid#查看垃圾回收器jinfo-flag+PrintGCvmid#开启查看GC打印日志信息
jhat:分析heapdump文件,在浏览器上查看分析结果
jhat-help#查看jhat所有命令参数信息jhatC:\Users\Administrator\Desktop\heap.hprof
jstack:生成虚拟机当前时刻的线程快照,可以进行日志分析,定位线上问题。
死锁:A线程和B线程相互获取资源,都在等待对方,导致死锁
publicclassDeadLockDemo { privatestaticObjectresource1=newObject();//资源 1privatestaticObjectresource2=newObject();//资源 2publicstaticvoidmain(String[] args) { newThread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() +"get resource1"); try { Thread.sleep(1000); } catch (InterruptedExceptione) { e.printStackTrace(); } System.out.println(Thread.currentThread() +"waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() +"get resource2"); } } }, "线程 1").start(); newThread(() -> { synchronized (resource2) { System.out.println(Thread.currentThread() +"get resource2"); try { Thread.sleep(1000); } catch (InterruptedExceptione) { 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.hprofpid#b表示二进制,生成文件heap.profjmap-heappid#内存区块信息
此时可以配合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
三个jar包引入pom文件:Btrace-agent.jar、Btrace-boot.jar、Btrace-client.jar
@Btrace注解:
clazz="com.study.mt.testController",method="arg1",localtion= (kind.ENTRY)) (
命令:
jps-lbtracepidprintArgSimple.java
可以采用命令启动,也可以在jvisualvm中使用
Btrace使用:
拦截方法:
普通方法, (clazz=" ",method=" ") 构造方法: (clazz="",method="<init>") 拦截同名函数,用参数区分
拦截时机:入口、运行、结束等
kind.Entry:入口,默认值kinf.RETURN:返回kind.THROW:异常kind.LINE=行
异常吞掉也没关系,BTrace也可以追踪,方便排查问题
BTrace只能本地运行,如果需要远程连接,则需要修改源代码
拦截this、参数、返回值:
this:入参:可以用AnyType,也可以用真实类型,同名的用真实的返回值:
其他:获取对象的值
简单类型:直接获取复杂类型:发射、类名+属性名
注意:生产环境下使用,需要注意被修改的字节码不会被还原
tomcat性能调优:首先需要修改tomcat的配置文件:tocat-user.xml、添加manager.xml:
tocat-user.xml添加几个角色信息:
<rolerolename="tomcat"/><rolerolename="manager-status"/><rolerolename="manager-gui"/><roleusername="tomcat"password="tomcat"roles="tomcat,managet-status,managet-gui"/>
manager.xml配置如下信息:
<contextprovileged="true"antiResourceLock="false"docBase='${catalina.home}/webapps/manager'><ValveclassName="org.apache.catalina.valves.RemoteAddrValve"allow="^192.168.*$"/></Context>
访问远程tomcat的管理页面,可以在server.status中查看到jvm参数信息。
除了使用tomcat的管理页面看到tomcat的jvm信息之外,还可以通过psi_probe监控看到相关参数信息,需要配置tomcat-user.xml和manager.xml的配置,放入到tomcat下面即可。