JVM实战学习——排查java程序 磁盘IO占用过高、CPU占用过高(pidstat)

JVM实战学习——排查java程序 磁盘IO占用过高、CPU占用过高、内存占用过高(pidstat)

一、排查cpu高占用

1.示例代码

使用以下代码,启动的服务会产生cpu资源大量占用的情况
1)占有大量CPU资源
2)启动类

2.查询项目进程

1)使用 jps 命令查询项目启动的进程
[root]# jps
15539 jar     ## 其中15539就是项目进程
1349 -- process information unavailable
15673 Jps
2)或者使用 ps -ef | grep java 同样可以查询进程号
[root]# ps -ef | grep java

##   其中 15539 就是项目进程
root     15539  3982 98 11:26 pts/0    00:03:12 java -jar study-spring-app-1.0-SNAPSHOT.jar
root     16139  6845  0 11:30 pts/2    00:00:00 grep java

3.使用 pidstat 工具查询cpu占用情况

## -p 指定进程号
## 15539 即进程号 紧跟 -p后面
## -t 展示进程下的线程资源占用情况
## 1 每秒刷新1次
## 3 共刷新三次

[root]# pidstat -p 15539 -t 1 3

## 通过查询出的信息可以检测到 线程号:15579   占用了大量的cpu资源,达到99%

Average:         TGID       TID    %usr %system  %guest    %CPU   CPU  Command
Average:        15539         -   99.00    0.00    0.00   99.00     -  java
-----        中间省略若干线程        ----------
Average:            -     15577    0.00    0.00    0.00    0.00     -  |__http-nio-8080-A
Average:            -     15579   99.00    0.00    0.00   99.00     -  |__Thread-2
Average:            -     15580    0.00    0.00    0.00    0.00     -  |__Thread-3
Average:            -     15581    0.00    0.00    0.00    0.00     -  |__Thread-4
Average:            -     15582    0.00    0.00    0.00    0.00     -  |__Thread-5


4. 使用jstack工具打印堆栈信息

## 15539 进程号 
## > jstack.text 将堆栈信息打到 jstack.text 文件中

[root]# jstack 15539 > jstack.text

5.根据线程ID(15579),在jstack.text中查询对应的堆栈信息

注意 此处根据 pidstat获取的线程号是 十进制。但是 jstack打印的堆栈信息中的nid是 十六进制,因此需要做一层进制转换,15579转十六进制为3cdb

## 根据3cdb检索堆栈信息,即可找到对应类,及其行数(FullCPUTask.java:15)

"Thread-2" #26 prio=5 os_prio=0 tid=0x00007f8118aa6800 nid=0x3cdb runnable [0x00007f80eadf0000]
   java.lang.Thread.State: RUNNABLE
	at c_6_1_4.FullCPUTask.run(FullCPUTask.java:15)
	at java.lang.Thread.run(Thread.java:748)

二、排查磁盘IO频繁

1.示例代码

使用以下代码,启动的服务会产生磁盘IO频繁的情况
1)磁盘IO频繁程序
2)启动类

2.查询项目进程

1)使用 jps 命令查询项目启动的进程
[root]# jps 
4833 jar	## 其中4833就是项目进程
1349 -- process information unavailable
4911 Jps

2)或者使用 ps -ef | grep java 同样可以查询进程号
[root]# ps -ef | grep java

##   其中 4833  就是项目进程
root      4833  3982 96 13:40 pts/0    00:00:40 java -jar study-spring-app-1.0-SNAPSHOT.jar
root      4982  6845  0 13:41 pts/2    00:00:00 grep java

3.使用 pidstat 工具查询磁盘IO频繁情况

## -p 指定进程号
## 4883 即进程号 紧跟 -p后面
## -t 展示进程下的线程资源占用情况
## -d 展示进程下的线程IO占用情况
## 1 每秒刷新1次
## 3 共刷新三次

[root]# pidstat -p 4833 -t -d 1 3

## 通过查询出的信息可以检测到 线程号:4890 占用了大量的磁盘IO

Average:         TGID       TID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
Average:         4833         -      0.00    848.00    848.00  java
Average:            -      4833      0.00      0.00      0.00  |__java
-----------   省略其他不相干线程 -------------
Average:            -      4890      0.00    848.00    848.00  |__Thread-2
Average:            -      4891      0.00      0.00      0.00  |__Thread-3
Average:            -      4892      0.00      0.00      0.00  |__Thread-4
Average:            -      4893      0.00      0.00      0.00  |__Thread-5
Average:            -      5886      0.00      0.00      0.00  |__Attach


4. 使用jstack工具打印堆栈信息

## 4833 进程号 
## > jstack.text 将堆栈信息打到 jstack.text 文件中

[root]# jstack 4833 > jstack.text

5.根据线程ID(4890),在jstack.text中查询对应的堆栈信息

注意 此处根据 pidstat获取的线程号是 十进制。但是 jstack打印的堆栈信息中的nid是 十六进制,因此需要做一层进制转换,4890转十六进制为131a

## 根据3cdb检索堆栈信息,即可找到对应类,及其行数(FullIOTask.java:22)

"Thread-2" #26 prio=5 os_prio=0 tid=0x00007fc554afa000 nid=0x131a runnable [0x00007fc540a3f000]
   java.lang.Thread.State: RUNNABLE
	at java.io.FileOutputStream.write(Native Method)
	at java.io.FileOutputStream.write(FileOutputStream.java:290)
	at c_6_1_4.FullIOTask.run(FullIOTask.java:22)
	at java.lang.Thread.run(Thread.java:748)

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值