Java进程CPU占用太高的问题定位

1. top获取占用CPU高的进程ID
top
进程pid=26850


top显示信息,需要关注的相关信息:
* load average:反映了任务队列的平均长度。如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高
* %us:用户CPU时间百分比。如果此值过高,可能是代码中存在死循环、或是频繁GC等
* %sy:系统CPU时间百分比。如果此值过高,可能是系统线程竞争激烈,上下文切换过多,应当减少线程数
* %wa:等待输入输出CPU时间百分比。如果此值过高,说明系统IO速度过慢,CPU大部分时间都在等待IO完成
* %hi:硬件中断CPU百分比。当硬件中断发生时,CPU会优先去处理,例如网卡收包会产生硬件中断,会优先处理
* swap used:被使用的swap。内存不住时才会用到,此值过高代表系统因为内存不足而导致频繁的换入、换出操作,这样会影响效率,应增大内存量
* %CPU:进程使用CPU的百分比




2. top -H -p 获取进程中线程信息
或top 然后H
top -H -p 26850
得到3个高消耗的线程PID:
26857
26853
26855


3.获取最高的线程pid(十进制->十六进制)
[root@localhost ~]# python -c "print hex(26857)"
0x68e9

[root@localhost ~]# printf "0x%x \n" 26857
0x68e9 
[root@localhost ~]#


4.查看线程堆栈信息 jstack <进程PID> |grep <线程PID> 
可以结合grep参数 -A,-B,-C,控制限制关键字之前、之后、前后 N行
查看对应的堆栈信息,找到可能存在问题的代码
通过jstack,可以查看某个进程的当前线程栈运行情况,定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等


jstack 26850 |grep 0x68e9


[root@localhost ~]# jstack 26850 |grep -A20 0x68e9 
"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007fc190025800 nid=0x68e9 runnable 


"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007fc190027800 nid=0x68ea runnable 


"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007fc190029800 nid=0x68eb runnable 


"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007fc19002b000 nid=0x68ec runnable 


"VM Periodic Task Thread" os_prio=0 tid=0x00007fc19021c000 nid=0x68f6 waiting on condition 


JNI global references: 322


[root@localhost ~]# 


发现线程耗CPU高,主要在GC回收处理。


5. pstack:可以查看某个进程的当前线程栈运行情况
pstack 进程ID




6. jstat查看gc情况


[root@localhost ~]# jstat -gc 26850  1000  5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
903680.0 903680.0  0.0    0.0   904192.0 904192.0 5423104.0  5423017.1  97792.0 92193.5 11520.0 10002.9   1287   85.160  694  7247.812 7332.972
903680.0 903680.0  0.0    0.0   904192.0 904192.0 5423104.0  5423017.1  97792.0 92193.5 11520.0 10002.9   1287   85.160  694  7247.812 7332.972
903680.0 903680.0  0.0    0.0   904192.0 904192.0 5423104.0  5423017.1  97792.0 92193.5 11520.0 10002.9   1287   85.160  694  7247.812 7332.972
903680.0 903680.0  0.0    0.0   904192.0 904192.0 5423104.0  5423017.1  97792.0 92193.5 11520.0 10002.9   1287   85.160  694  7247.812 7332.972
903680.0 903680.0  0.0    0.0   904192.0 821434.1 5423104.0  5423017.1  97792.0 92193.5 11520.0 10002.9   1287   85.160  694  7256.763 7341.923
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# jstat -gcutil 26850  1000  5 
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00 100.00 100.00  94.28  86.83   1287   85.160   696 7263.066 7348.226
  0.00   0.00 100.00 100.00  94.28  86.83   1287   85.160   696 7263.066 7348.226
  0.00   0.00 100.00 100.00  94.28  86.83   1287   85.160   696 7263.066 7348.226
  0.00   0.00 100.00 100.00  94.28  86.83   1287   85.160   696 7263.066 7348.226
  0.00   0.00 100.00 100.00  94.28  86.83   1287   85.160   696 7263.066 7348.226
[root@localhost ~]# 


7.jstat -gccause 查看信息
[root@localhost ~]# jstat -gccause 26850 1s
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
  0.00   0.00  90.21  99.99  94.31  86.88   1287   85.160   800 8246.108 8331.268 Allocation Failure   No GC               
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.31  86.88   1287   85.160   801 8246.108 8331.268 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.33  86.90   1287   85.160   802 8254.123 8339.284 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.33  86.90   1287   85.160   802 8254.123 8339.284 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.33  86.90   1287   85.160   802 8254.123 8339.284 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.33  86.90   1287   85.160   802 8254.123 8339.284 Allocation Failure   Ergonomics          
  0.00   0.00 100.00  99.99  94.33  86.90   1287   85.160   802 8254.123 8339.284 Allocation Failure   Ergonomics          
^C[root@localhost ~]# 


8.为何如此频发gc,继续定位哪里占用内存
jmap -histo[:live] [pid] 把程序的对象情况打印出来
打印每个class的实例数目,内存占用,类全名信息。VM的内部类名字开头会加上前缀”*”。:live可选参数,用来指定只统计活的对象数量。
如果要dump下来的话,用命令:jmap -dump:format=b,file=mydump.dat


jmap -histo:live | less


 num     #instances         #bytes  class name
----------------------------------------------
   1:     110988441     2663722584  com.xxx.demo.proc.ChangeEntry$RowValue
   2:      24670473     1012841688  [B
   3:       4155237      653276216  [Ljava.lang.Object;
   4:      16442770      526168640  java.sql.Timestamp
   5:      12352444      296458656  java.lang.Long
   6:       8422230      259114432  [C
   7:       8418832      202051968  java.lang.String
   8:       8241076      197785824  java.lang.Double
   9:       4111117      164444680  java.math.BigInteger
  10:       4110711      164428440  java.math.BigDecimal
  11:       4214003      106784312  [I
  12:       4125711       99017064  java.util.ArrayList


通过代码定位,发现:
com.xxx.demo.proc.ChangeEntry这个类对象太多了,大量占用内存。

你可能感兴趣的:(开发,常见问题)