概要描述
本案例简单介绍几个JVM内存分析相关的命令,以及案例解析;
本案例环境:TDH 5.2.2 inceptor-server 的内存分析
详细说明
JVM内存模型比较复杂,本文只简单介绍命令的使用方法:
由于 TDH 5.2.2 版本已经容器化了,需要进入 pod 内查看 java 进程的信息,以下演示均是在 pod 内演示;
进入 pod 的方法参考如下命令:
[root@tdh6-161~]# kubectl get pods |grep inceptor-server
inceptor-server-argodbcomputing1-6d8b7586f4-89crm 1/1 Running 0 5d1h
inceptor-server-inceptor1-d9ccb8648-7tlpr 1/1 Running 1 13d
[root@tdh6-161~]# kubectl exec -ti inceptor-server-inceptor1-d9ccb8648-7tlpr bash
[root@tdh6-161 ~]# jps
458 InceptorServer2
15373 Jps
[root@tdh6-161 ~]#
jps
jps 作用是显示当前系统的 java 进程情况,及其 id 号
jps [-q] [-mlvV] [hostid]
例如:查看当前系统下,当前用户运行的java进程( -v可以输出当前java进程的启动参数)
jstat
jstat (JVM statistics Monitoring) 是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集等运行数据。
jstat -option [-t] [-h lines] vmid [interval [count]]
例如:查看 vmid 为 428 的进程的 GC 统计概述,每隔 1000ms统计一次,共输出 5 次( -gc打印的内容更详细,但是可读性不如 -gcutil)
jmap
jmap 可以生成 java 程序的 dump 文件,也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列;
一般在运行缓慢、性能下降时收集;
jmap [option] pid
例如:查看 pid 为 428 的进程的堆的活对象统计,包括对象数、内存大小( :live 则只统计这个jmap 触发的 fgc 之后依然保留下来的对象,因此强烈建议带上live)
$ sudo -u hive jmap -histo:live 428 >> /var/log/inceptor1/jmap.log
jmap 主要看哪些对象占用了大量的内存空间,占用的是否合理等信息,需要同时关注数量(instances),大小(bytes);
jmap 信息的最后的一行 Total 显示了对象的数量以及他们使用的内存信息;
jmap 还有一个更加详细的堆内存信息 heapdump,一般该文件比较大,10G 以上,可以在出问题的时候收集保存一下,后续如果需要再提供即可。收集方法如下:
例如:查看 pid 为 428 的进程的堆内存信息:
$ sudo -u hive jmap -dump:live,format=b,file=heap-dump.bin 428
收集获得的文件在当前目录下,文件名为 heap-dump.bin。
jstack
jstack 是用于生成 java 虚拟机当前时刻的线程快照。
线程快照是当前 JVM 内每一个线程正在执行的方法堆栈的集合,一般在服务卡住的时候收集(如线程间死锁、死循环、请求外部资源导致的长时间等待等); 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
jstack [-l] pid
例如:查看pid为458进程对应的线程快照、各线程的运行情况等信息
jstack 主要看线程之间资源抢占情况,是分析线程执行快慢的一种方法;
jinfo
jinfo(JVM Configuration info) 是实时查看和调整虚拟机运行参数的命令。和 jps -v不同的地方是,jinfo 可以显示未指定的参数的值,也就是默认运行参数的值;
命令格式
jinfo [option] pid
例如:查看 pid 为428的进程的运行参数(如果不带任何参数,可以显示该进程对应的所有JVM信息)
$ jinfo -flags 428
jinfo在不加任何参数的情况下,输出内容比较详细,一般用来分析脏包;也可以用来检查启动参数是否正常;
附录
星环科技售后技术支持提供一键收集 jmap 与 jstack 的脚本,可以 联系星环科技全球技术支持中心 获取脚本;
getjvm.sh
使用方法如下:
[root@tdh-01~/mysh]# bash getjvm.sh inceptor1 jmap
2021-07-13 17:52:39 getjvm.sh Collect Jmap information of inceptor1 server on tdh-01 to /var/log/inceptor1/jmap successed
2021-07-13 17:52:42 getjvm.sh Collect Jmap information of inceptor1 metastore on tdh-01 to /var/log/inceptor1/jmap successed
2021-07-13 17:52:47 getjvm.sh Collect Jmap information of inceptor1 executor on tdh-02 to /var/log/inceptor1/jmap successed
2021-07-13 17:52:51 getjvm.sh Collect Jmap information of inceptor1 executor on tdh-03 to /var/log/inceptor1/jmap successed
2021-07-13 17:52:56 getjvm.sh Collect Jmap information of inceptor1 executor on tdh-01 to /var/log/inceptor1/jmap successed
[root@tdh-01~/mysh]#