• Java程序性能监控工具



    系统性能监控:

    确定系统运行的整体状态,基本定位问题所在

    uptime命令

    [root@localhost ~]# uptime
    23:19:38 up 244 days, 3:39, 34 users, load average: 7.36, 7.81, 7.79

    ps,获取服务器有多少逻辑核心:grep 'model name' /proc/cpuinfo | wc -l,一般情况下load average除以逻辑核心数 < 0.7 认为CPU压力不大

    系统时间
    时间从开机到现在的运行时间
    连接数:每一个终端算一个连接
    1,5,15分钟内的系统平均负载:运行队列中的平均进程数。

    top命令

    第一行同uptime
    CPU、内存情况
    每个进程占CPU的情况

    可以知道哪个程序占用CPU最多

    vmstat命令

    可以统计系统的CPU,内存,swap,io等情况

    CPU占用率很高,上下文切换频繁、说明系统中有线程正在频繁切换。

    vmstat 1 4 指定采样频率和采样次数,每1秒采集1次,采集4次

    [root@localhost ~]# vmstat 1 4
    procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
    r b swpd free buff cache si so bi bo in cs us sy id wa st
    8 0 0 638328 31104 46136032 0 0 17 85 0 0 3 3 94 0 0
    7 0 0 636872 31112 46136076 0 0 128 1416 46076 129603 11 10 79 0 0
    7 0 0 636504 31112 46136308 0 0 0 996 45864 122568 11 10 79 0 0
    13 0 0 635540 31112 46136380 0 0 0 2972 48854 127109 11 12 77 0 0


    cs和us代表上下文切换。

    pidstat命令

    细致观察进程
    需要安装: yum install -y sysstat
    监控CPU
    监控IO
    监控内存


    pidstat -p 58 -u 1 3

    -p表示指定进程,进程id为58
    -u指定采样CPU,每1秒采样一次,采集3次

    [root@localhost ~]# pidstat -p 146603 -u 1 3
    Linux 3.10.0-514.el7.x86_64 (localhost.localdomain) 08/06/2018 _x86_64_ (32 CPU)
    11:34:26 PM UID PID %usr %system %guest %CPU CPU Command
    11:34:27 PM 992 146603 0.00 0.00 0.00 0.00 11 ssh
    11:34:28 PM 992 146603 0.00 0.00 0.00 0.00 11 ssh
    11:34:29 PM 992 146603 0.00 0.00 0.00 0.00 11 ssh
    Average: 992 146603 0.00 0.00 0.00 0.00 - ssh


    pidstat -p 58 -u 1 3 -t 
    -t参数:查看进程中线程的使用情况

    pidstat -p 58 -d 1 3 -t 
    -d 查看磁盘io的情况

    Java自带的工具

    查看java程序运行细节,进一步定位问题

    jps

    列出java进程,类似于ps命令
    -q可以指定jps只输出进程id,不输出类的短名称
    -m参数可以用于输出传递给java进程(主函数)的参数
    -l可以用于输出主函数的完整路径
    -v可以显示传递给jvm的参数

    支持远程监控(需要开启安全授权)

    jps 192.168.1.10

    安全授权

    在远程机器%JAVA_HOME%/bin/目录下存储jstatd.all.policy文件,内容如下:

    grant codebase "file:${java.home}/../lib/tools.jar" {
        permission java.security.AllPermission;
    };

    然后在进入jstatd.all.policy所在目录下,通过如下的命令启动RMI服务:

    ./jstatd -J-Djava.security.policy=jstatd.all.policy 

    或者

    ./jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.22.249

    jstat

    jstat -gcutil 9统计gc信息:

    说明:

    图中显示,FGC一共有3次,用时547毫秒,平均一次gc占用时间为547/3=182毫秒,结合JVM运行时长来看这个full gc是否合理,比如这个数据是jvm启动了一天之后的数据,即一天3次full gc,且每次182毫秒,对于平均响应时间为1s的应用来说这完全没有问题;如果是1小时3次,应用的响应时间为几十毫秒,这个就有影响了,GC的时间消耗是否合理是相对的。

    字段说明

    S0 年轻代中第1个幸存区已使用的占当前容量百分比

    S1 年轻代中第2个幸存区已使用的占当前容量百分比

    E  年轻代中Eden已经使用的占当前容量的百分比

    O  old代中Eden已经使用的占当前容量的百分比

    P  perm代中Eden已经使用的占当前容量的百分比

    YGC  JVM启动到采样时年轻代gc次数

    YGCT JVM启动到采样时年轻代gc所用时间

    FGC JVM启动到采样时old代(full gc)gc次数

    FGCT JVM启动到采样时old代(full gc)gc所用时间

    GCT JVM启动到采样时gc用的总时间

    支持远程监控(需开启安全授权)

    jstat -gcutil 1198@192.168.1.10

    jinfo

    可以用来查看正在运行的java应用程序的扩展参数,甚至支持在运行时,修改部分参数。
    -flag <name> 打印指定JVM的参数值
    -flag [+|-] <name> 设置指定JVM参数的布尔值
    -flag <name>=<value>:设置指定JVM参数的值

    显示了新生代对象晋升到老年代对象的最大年龄:
    [root@localhost ~]# jinfo -flag MaxTenuringThreshold 2972
    输出:-XX:MaxTenuringThreshold=15

    显示是否打印GC详细信息:
    [root@localhost ~]# jinfo -flag PrintGCDetails 23415
    -XX:-PrintGCDetails (-号代表false)

    运行时修改参数,控制是否输出GC日志(不用重启进程)
    [root@localhost ~]# jinfo -flag +PrintGCDetails 23415
    [root@localhost ~]# jinfo -flag PrintGCDetails 23415
    -XX:+PrintGCDetails

    jmap 

    3.1、生成java应用程序的堆快照和对象的统计信息
    jmap -histo 23415 > /home/bgq/s.txt

    [root@localhost ~]# cat /home/bgq/s.txt |less

    num #instances #bytes class name
    ----------------------------------------------
    1: 195451 21772752 [C
    2: 82717 18440736 [B
    3: 18116 16245400 [I

    输出默认是占用空间大小(#bytes)倒序显示。

    [I代表整数数组


    3.2、Dump堆
    jmap -dump:format=b,file=/home/bgq/heap.hprof 23415

    dump完成之后,通过工具打开这个文件。比如mat工具

    jstack

    打印线程dump,注意一定要用该进程的启动用户去拉,否则会报 Unable to open socket file: target process not responding or HotSpot VM not loaded 错误。

    -l 打印锁信息
    -m 打印java和native的帧信息
    -F 强制dump,当jstack没有响应时使用

    打印120这个pid的线程信息
    jstack 120 >> C:a.txt

    JStack 拉取的文件信息基本分为以下几个部分:
    该拉取快照的服务器时间
    JVM 版本
    以线程 ID(即 tid)升序依次列出当前进程中每个线程的调用栈
    死锁(如果有的话)
    阻塞锁链
    打开的锁链
    监视器解锁情况跟踪
    每个线程在等待什么资源,这个资源目前在被哪个线程 hold,尽在眼前。JStack 最好在压测时多次获取,找到的普遍存在的现象即为线程瓶颈所在。

    JConsole

    图形化监控工具
    可以查看java应用程序的运行情况,监控堆信息,永久区使用情况,类加载情况等。

    堆:新生代、老年代
    非堆:堆以外的内存,包括code cache、compressed class space

    Jvisual VM

    比jconsole更强大的工具
    多合一故障诊断和性能监控的可视化工具。

    性能监控:找到占用CPU时间最长的方法
    抽象器-->CPU

    分析堆Dump

    练习:
    运行一个程序ThreadBlockMain,期望输出Hello, World,结果在程序运行后,程序卡死,没有预期输出


    1、通过jps获取进程id号
    2、打印进程的线程信息:jstack 2300 > C: s.txt
    3、打开文件,查看,通过进程发现在等待一个socket receive


    练习2:
    java程序HoldCPUMain运行后,发现占用CPU很高,希望能找到原因。

    1、通过jps获取HoldCPUMain的进程id号
    2、uptime查看负载
    3、top命令,查看java程序CPU占用率100%
    4、pidstat -p 3455 1 3 -u -t
    打印CPU的线程输出情况,发现某个线程3467,占用CPU特别高
    3467转16进制:D8B(jstack获取的线程信息文件中,线程号以16进制呈现)
    jstack 3455 > C: s.txt

    然后根据jstack的线程调用信息,查看指定的代码行。

    练习3:
    死锁。

    如何从jstack的输出中找出死锁。

    看是不是有线程互相等待

    使用jvisualvm、jmc远程监控JVM

    https://blog.csdn.net/mn960mn/article/details/73958701

    IBM HeapAnalyzer简介使用

    https://blog.csdn.net/wwd0501/article/details/78657319

  • 相关阅读:
    SpringBoot2 application.properties方式加载配置文件
    php第三十节课
    php第二十九节课
    php第二十八节课
    php第二十七节课
    php第二十六节课
    php第二十五节课
    php第二十四节课
    DBDA
    php第二十三节课
  • 原文地址:https://www.cnblogs.com/byron0918/p/9434407.html
Copyright © 2020-2023  润新知