赞
踩
命令 cat /proc/cpuinfo
命令 lscpu
介绍关于CPU信息的几个重要细节。
如果是上述原因导致的慢的话,建议直接购买新的机器;
先看开头部分,up 后面是系统开机时间;users代表用户数 load average:是系统最近1min、5min、15min的CPU荷载信息.
total:当前有的任务数量
running:正在运行的任务数量
sleeping:处于睡眠状态 的进程数量
stopped:停止的进程数量
zombie:基本不动的进程数量
us:用户态进程占用CPU时间百分比
sy:内核占用CPU时间百分比
ni:renice值为负的任务的用户态进程的CPU时间百分比。nice是优先级的意思
id:空闲CPU时间百分比 0.0%wa:等待I/O的CPU时间百分比
hi:CPU硬中断时间百分比
si:CPU软中断时间百分比
根据 %CPU
列与 %MEM
列,确定占用较多资源的进程
k
。CPU 空闲但高负载情况处理
Load average 是 CPU 负载的评估,其值越高,说明其任务队列越长,处于等待执行的任务越多。
通过 top 观察,类似如下图所示,CPU 很空闲,但是 load average 却非常高。
执行以下命令,查看进程状态,并检查是否存在 D 状态进程。 命令 ps -axjf
D 状态指不可中断的睡眠状态。该状态进程无法被杀死,也无法自行退出。
若出现较多 D 状态进程,可通过恢复该进程依赖资源或重启系统进行解决。
根据top分析出cpu过高的进程;
(图片来源于网络,copy的)
根据top -Hp 命令查看该进程下各个线程的cpu使用情况; 命令:top -Hp 23344
上图中可以看出pid为25077的线程占了较多的cpu资源,利用jstack命令可以继续查看该线程当前的堆栈状态。
通过top命令定位到cpu占用率较高的线程之后,继续使用jstack pid
命令查看当前java进程的堆栈状态
jstack命令生成的thread dump信息包含了JVM中所有存活的线程,为了分析指定线程,必须找出对应线程的调用栈,应该如何找?
在top命令中,已经获取到了占用cpu资源较高的线程pid,将该pid转成16进制的值,在thread dump中每个线程都有一个nid,找到对应的nid即可;隔段时间再执行一次stack命令获取thread dump,区分两份dump是否有差别,在nid=0x246c的线程调用栈中,发现该线程一直在执行JstackCase类第33行的calculate方法,得到这个信息,就可以检查对应的代码是否有问题。
除了上述的分析,大多数情况下会基于thead dump分析当前各个线程的运行情况,如是否存在死锁、是否存在一个线程长时间持有锁不放等等。
在dump中,线程一般存在如下几种状态:
1、RUNNABLE,线程处于执行中
2、BLOCKED,线程被阻塞
3、WAITING,线程正在等待
很明显:线程1获取到锁,处于RUNNABLE状态,线程2处于BLOCK状态
1、locked <0x000000076bf62208>
说明线程1对地址为0x000000076bf62208对象进行了加锁;
2、waiting to lock <0x000000076bf62208>
说明线程2在等待地址为0x000000076bf62208对象上的锁;
3、waiting for monitor entry [0x000000001e21f000]
说明线程1是通过synchronized关键字进入了监视器的临界区,并处于"Entry Set"队列,等待monitor,具体实现可以参考深入分析synchronized的JVM实现;
实例2:通过wait挂起线程
- static class Task implements Runnable {
- @Override
- public void run() {
- synchronized (lock) {
- try {
- lock.wait();
- //TimeUnit.SECONDS.sleep(100000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
dump结果
线程1和2都处于WAITING状态
1、线程1和2都是先locked <0x000000076bf62500>
,再waiting on <0x000000076bf62500>
,之所以先锁再等同一个对象,是因为wait方法需要先通过synchronized获得该地址对象的monitor;
2、waiting on <0x000000076bf62500>
说明线程执行了wait方法之后,释放了monitor,进入到"Wait Set"队列,等待其它线程执行地址为0x000000076bf62500对象的notify方法,并唤醒自己;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。