转于:http://www.cnblogs.com/lidabo/p/4738113.htmlphp
能够用下面的命令将 cpu 占用率高的线程找出来: ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpujava
这个命令首先指定参数'H',显示线程相关的信息,格式输出中包含:user,pid,ppid,tid,time,%cpu,cmd,而后再用%cpu字段进行排序。这样就能够找到占用处理器的线程了。linux
直接使用 ps Hh -eo pid,tid,pcpu | sort -nk3 |tail 获取对于的进程号和线程号,而后跳转到3. 查看哪一个进程线程占用cpu太高; top / ps -aux, 得到进程号 肯定哪一个线程占用cpu太高,进入进程号的目录:/proc/pid/task, 执行:grep SleepAVG **/status | sort -k2,2 | head, 肯定cpu占用较高的线程号。 使用kill -3 pid 会打印线程堆栈的状况ios
在 Linux 下 top 工具能够显示 cpu 的平均利用率(user,nice,system,idle,iowait,irq,softirq,etc.),能够显示每一个 cpu 的利用率。可是没法显示每一个线程的 cpu 利用率状况,这时就可能出现这种状况,总的 cpu 利用率中 user 或 system 很高,可是用进程的 cpu 占用率进行排序时,没有进程的 user 或 system 与之对应。nginx
/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通讯的接口。用户和应用程序能够经过/proc获得系统的信息,并能够改变内核的某些参数。因为系统的信息,如进程,是动态改变的,因此用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。算法
/proc目录中有一些以数字命名的目录,它们是进程目录。系统中当前运行的每个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。此外,在Linux2.6.0-test6以上的版本中/proc/pid目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。shell
该文件中存放了有关 cpu的相关信息(型号,缓存大小等)。express
[zhengangen@buick ~]$ cat /proc/cpuinfoapi
processor : 0
vendor_id : GenuineIntel
cpu family : 15
model : 4
model name : Intel(R)Xeon(TM) CPU 3.00GHz
stepping : 10
cpu MHz : 3001.177
cache size : 2048 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 1
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 5
wp : yes
flags : fpu vme de psetsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsrsse sse2 ss ht tm pbe lm pni monitor ds_cpl cid xtpr
bogomips : 6004.52
说明:如下只解释对咱们计算Cpu使用率有用的相关参数。
参数 解释
processor (0) cpu的一个物理标识
结论1:能够经过该文件根据processor出现的次数统计cpu的逻辑个数(包括多核、超线程)。
该文件包含了全部CPU活动的信息,该文件中的全部值都是从系统启动开始累计到当前时刻。不一样内核版本中该文件的格式可能不大一致,如下经过实例来讲明数据该文件中各字段的含义。
实例数据:2.6.24-24版本上的
fjzag@fjzag-desktop:~$cat /proc/stat
cpu 38082 627 27594 89390812256 581 895 0 0
cpu022880 472 16855 430287 10617 576 661 0 0
cpu115202 154 10739 463620 1639 4 234 0 0
intr120053 222 2686 0 1 1 0 5 0 3 0 0 0 47302 0 0 34194 29775 0 5019 845 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt1434984
btime1252028243
processes8113
procs_running1
procs_blocked0
第一行的数值表示的是CPU总的使用状况,因此咱们只要用第一行的数字计算就能够了。下表解析第一行各数值的含义:
参数 解析(单位:jiffies)
(jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大体可理解为操做系统进程调度的最小时间片,不一样linux内核可能值有不一样,一般在1ms到10ms之间)
user (38082) 从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。
nice (627) 从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
system (27594) 从系统启动开始累计到当前时刻,处于核心态的运行时间
idle (893908) 从系统启动开始累计到当前时刻,除IO等待时间之外的其它等待时间iowait (12256) 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)
irq (581) 从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)
softirq (895) 从系统启动开始累计到当前时刻,软中断时间(since2.6.0-test4)stealstolen(0) which is the time spent in otheroperating systems when running in a virtualized environment(since 2.6.11)
guest(0) whichis the time spent running a virtual CPU for guest operating systems under the control ofthe Linux kernel(since 2.6.24)
结论2:总的cpu时间totalCpuTime = user + nice+ system + idle + iowait + irq + softirq + stealstolen + guest
该文件包含了某一进程全部的活动的信息,该文件中的全部值都是从系统启动开始累计
到当前时刻。如下经过实例数据来讲明该文件中各字段的含义。
[zhengangen@buick ~]# cat/proc/6873/stat
6873 (a.out) R 6723 6873 6723 34819 6873 8388608 77 0 0 0 41958 31 0 0 25 0 3 05882654 1409024 56 4294967295 134512640 134513720 3215579040 0 2097798 0 0 0 00 0 0 17 0 0 0
说明:如下只解释对咱们计算Cpu使用率有用相关参数
参数 解释
pid=6873 进程号
utime=1587 该任务在用户态运行的时间,单位为jiffies
stime=41958 该任务在核心态运行的时间,单位为jiffies
cutime=0 全部已死线程在用户态运行的时间,单位为jiffies
cstime=0 全部已死在核心态运行的时间,单位为jiffies
结论3:进程的总Cpu时间processCpuTime = utime +stime + cutime + cstime,该值包括其全部线程的cpu时间。
该文件包含了某一进程全部的活动的信息,该文件中的全部值都是从系统启动开始累计到当前时刻。该文件的内容格式以及各字段的含义同/proc/<pid>/stat文件。
注意,该文件中的tid字段表示的再也不是进程号,而是linux中的轻量级进程(lwp),即咱们一般所说的线程。
结论4:线程Cpu时间threadCpuTime = utime +stime
经过ps命令能够查看系统中相关进程的Cpu使用率的信息。如下在linux man文档中对ps命令输出中有关cpu使用率的解释:
CPU usage is currentlyexpressed as the percentage of time spent running during the entire lifetime ofa process. This is not ideal, and it does not conform to the standards that psotherwise conforms to. CPU usage is unlikely to add up to exactly 100%.
%cpu cpu utilization of the process in"##.#" format. It is the CPU time used divided by the timethe process has been running (cputime/realtime ratio), expressed as apercentage. It will not add up to 100% unless you are lucky.
结论5:ps命令算出来的cpu使用率相对于进程启动时的平均值,随着进程运行时间的增大,该值会趋向于平缓。
经过top命令能够查看系统中相关进程的实时信息(cpu使用率等)。如下是man文档中对top命令输出中有关进程cpu使用率的解释。
#C -- Last used CPU (SMP) Anumber representing the last used processor. In a true SMP environment this will likely change frequently since the kernel intentionally usesweak affinity. Also, the very act ofrunning top may break this weak affinity and cause more processes to change CPUs more often (because of the extra demand for cputime).
%CPU -- CPUusage The task’s share ofthe elapsed CPU time since the last screen update, expressed as a percent-ageof total CPU time. In a true SMP environment, if Irix mode is Off, top will operate in Solaris modewhere a task’s cpu usage will be divided by the total number of CPUs.
结论6:某一个线程在其运行期间其所使用的cpu可能会发生变化。
结论7:在多核的状况下top命令输出的cpu使用率实质是按cpu个数*100%计算的。
经过读取/proc/stat 、/proc/<pid>/stat、/proc/<pid>/task/<tid>/stat以及/proc/cpuinfo这几个文件获取总的Cpu时间、进程的Cpu时间、线程的Cpu时间以及Cpu的个数的信息,而后经过必定的算法进行计算(采样两个足够短的时间间隔的Cpu快照与进程快照来计算进程的Cpu使用率)。
一、 采样两个足够短的时间间隔的Cpu快照,分别记做t1,t2,其中t一、t2的结构均为:
(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
二、 计算总的Cpu时间片totalCpuTime
a) 把第一次的全部cpu使用状况求和,获得s1;
b) 把第二次的全部cpu使用状况求和,获得s2;
c) s2 - s1获得这个时间间隔内的全部时间片,即totalCpuTime = j2 - j1 ;
三、计算空闲时间idle
idle对应第四列的数据,用第二次的第四列- 第一次的第四列便可
idle=第二次的第四列- 第一次的第四列
六、计算cpu使用率
pcpu =100* (total-idle)/total
1. 采样两个足够短的时间间隔的cpu快照与进程快照,
a) 每个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
b) 每个进程快照均为 (utime、stime、cutime、cstime)的4元组;
2. 分别根据结论二、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别记做:totalCpuTime一、totalCpuTime二、processCpuTime一、processCpuTime2
3. 计算该进程的cpu使用率pcpu = 100*(processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,若是是多核状况下还需乘以cpu的个数);
实验一: 监控一空循环的进程的cpu使用率。 |
|
说明:左边的数据是按以上算法获得的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。 |
|
按以上方法计算获得的cpu使用率 |
经过top命令获得的 |
99.50083 98.333336 98.0 98.83138 99.0 99.0 99.83361 98.83527 98.4975
|
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:00.74 java 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:03.71 java 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:06.67 java 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:09.63 java 7639 fjzag 20 0 206m 10m 7136 S 98 2.2 1:12.59 java 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:15.55 java 7639 fjzag 20 0 206m 10m 7136 S 100 2.2 1:18.55 java 7639 fjzag 20 0 206m 10m 7136 S 100 2.2 1:21.54 java 7639 fjzag 20 0 206m 10m 7136 S 99 2.2 1:24.52 java 7639 fjzag 20 0 206m 10m 7136 S 98 2.2 1:27.46 java |
实验二: 监控jconsole进程的cpu使用率。 |
|
说明:左边的数据是按以上算法获得的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。 |
|
按以上方法计算获得的cpu使用率 |
经过top命令获得的 |
8.681135 12.0 10.350584 7.6539097 7.6539097 5.0 13.021703 11.0 8.666667 |
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7753 fjzag 20 0 252m 72m 22m S 10 14.4 0:18.70 jconsole 7753 fjzag 20 0 252m 72m 22m S 12 14.4 0:19.07 jconsole 7753 fjzag 20 0 252m 72m 22m S 11 14.4 0:19.39 jconsole 7753 fjzag 20 0 252m 72m 22m S 7 14.4 0:19.61 jconsole 7753 fjzag 20 0 252m 72m 22m S 7 14.4 0:19.83 jconsole 7753 fjzag 20 0 252m 72m 22m S 5 14.4 0:19.97 jconsole 7753 fjzag 20 0 252m 72m 22m S 14 14.4 0:20.38 jconsole 7753 fjzag 20 0 252m 72m 22m S 10 14.4 0:20.68 jconsole 7753 fjzag 20 0 252m 72m 22m S 9 14.5 0:20.96 jconsole |
1. 采样两个足够短的时间隔的cpu快照与线程快照,
a) 每个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstealon、guest)的9元组;
b) 每个线程快照均为 (utime、stime)的2元组;
2. 分别根据结论二、结论4计算出两个时刻的总的cpu时间与线程的cpu时间,分别记做:totalCpuTime一、totalCpuTime二、threadCpuTime一、threadCpuTime2
3. 计算该线程的cpu使用率pcpu = 100*( threadCpuTime2– threadCpuTime1) / (totalCpuTime2– totalCpuTime1) (按100%计算,若是是多核状况下还需乘以cpu的个数);
实验一: 监控一空循环的线程的cpu使用率。 |
|
说明:左边的数据是按以上算法获得的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。 |
|
按以上方法计算获得的cpu使用率 |
经过top命令获得的 |
98.83138 97.00997 96.98997 97.49583 98.169716 96.8386 97.333336 93.82304 98.66667 |
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7649 fjzag 20 0 206m 10m 7136 R 97 2.2 7:22.94 java 7649 fjzag 20 0 206m 10m 7136 R 97 2.2 7:25.86 java 7649 fjzag 20 0 206m 10m 7136 R 97 2.2 7:28.76 java 7649 fjzag 20 0 206m 10m 7136 R 99 2.2 7:31.72 java 7649 fjzag 20 0 206m 10m 7136 R 98 2.2 7:34.65 java 7649 fjzag 20 0 206m 10m 7136 R 96 2.2 7:37.53 java 7649 fjzag 20 0 206m 10m 7136 R 98 2.2 7:40.47 java 7649 fjzag 20 0 206m 10m 7136 R 96 2.2 7:43.34 java 7649 fjzag 20 0 206m 10m 7136 R 97 2.2 7:46.25 java |
实验二: 监控jconsole程序某一线程的cpu使用率。 |
|
说明:左边的数据是按以上算法获得的数据,其中采样的时间间隔与top命令刷新屏幕的时间间隔相同。 |
|
按以上方法计算获得的cpu使用率 |
经过top命令获得的 |
1.3400335 6.644518 1.3333334 0.6677796 0.6666667 1.3333334 1.3333334 |
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7755 fjzag 20 0 251m 72m 22m S 1 14.4 0:11.92 jconsole 7755 fjzag 20 0 251m 72m 22m S 7 14.4 0:12.12 jconsole 7755 fjzag 20 0 251m 72m 22m S 2 14.4 0:12.18 jconsole 7755 fjzag 20 0 251m 72m 22m S 0 14.4 0:12.18 jconsole 7755 fjzag 20 0 251m 72m 22m S 1 14.4 0:12.20 jconsole 7755 fjzag 20 0 251m 72m 22m S 1 14.4 0:12.24 jconsole 7755 fjzag 20 0 251m 72m 22m S 1 14.4 0:12.28 jconsole |
如下经过实验数据来讲明多核状况下某一进程cpu使用率是按cpu个数*100%计算的.
在双核的状况下做的一组实验,第一组数据是经过ps -eLo pid,lwp,pcpu | grep 9140命令查看进程号为9140的进程中各线程的详细信息。第二组数据是经过 ps命令查看进程号为9140进程的cpu使用率。
pid lwp %cpu
9140 9140 0.0 9140 9141 0.0 9140 9142 0.0 9140 9143 0.0 9140 9144 0.0 9140 9149 0.0 9140 9150 0.0 9140 9151 0.0 9140 9152 0.1 9140 9153 96.6 该线程是一个空循环 9140 9154 95.9 该线程是一个空循环
以上除了红色标注出来的两个线程之外,其余的线程都是后台线程。
pid %cpu
9140 193
在单核的状况下做的一组实验,第一组数据是经过ps -eLo pid,lwp,pcpu | grep 6137命令查看进程号为6137的进程中各线程的详细信息。第二组数据是经过 ps命令查看进程号为6137进程的cpu使用率。
pid lwp %cpu
6137 6137 0.0
6137 6138 0.1
6137 6143 0.0
6137 6144 0.0
6137 6145 0.0
6137 6146 0.0
6137 6147 0.0
6137 6148 0.0
6137 6149 0.0
6137 6150 46.9 空循环线程
6137 6151 46.9 空循环线程
以上除了红色标注出来的两个线程之外,其余的线程都是后台线程。
pid %cpu
6137 92.9
1. 不一样内核版本/proc/stat文件格式不大一致。/proc/stat文件中第一行为总的cpu使用状况。
各个版本都有的4个字段: user、nice、system、idle
2.5.41版本新增字段:iowait
2.6.0-test4新增字段:irq、softirq
2.6.11新增字段:stealstolen: which is thetime spent in other operating
systems whenrunning in a virtualized environment
2.6.24新增字段:guest: whichis the time spent running a virtual CPU for guest operating systems under the control ofthe Linux kernel
2./proc/pid/task目录是Linux 2.6.0-test6以后才有的功能。
3.关于出现cpu使用率为负的状况,目前想到的解决方案是若是出现负值,连续采样计算cpu使用率直到为非负。
4.有些线程生命周期较短,可能在咱们采样期间就已经死掉了.
php-cgi进程占用cpu资源过多负载高的缘由分析及解决步骤
服务器环境:redhat linux 5.5 , nginx , phpfastcgi
在此环境下,通常php-cgi运行是很是稳定的,但也遇到过php-cgi占用太多cpu资源而致使服务器响应过慢,我所遇到的php-cgi进程占用cpu资源过多的缘由有:
1. 一些php的扩展与php版本兼容存在问题,实践证实 eAccelerater与某些php版本兼容存在问题,具体表现时启动php-cgi进程后,运行10多分钟,奇慢无比,但静态资源访问很快,服务器负载也很正常(说明nginx没有问题,而是php-cgi进程的问题),解决办法就是从php.ini中禁止掉eAccelerater模块,再重启php-cgi进程便可
2. 程序中可能存在死循环,致使服务器负载超高(使用top指令查看负载高达100+), 须要借助Linux的proc虚拟文件系统找到具体的问题程序
3. php程序不合理使用session , 这个发生在开源微博记事狗程序上,具体表现是有少许php-cgi进程(不超过10个)的cpu使用率达98%以上, 服务器负载在4-8之间,这个问题的解决,仍然须要借助Linux的proc文件系统找出缘由。
4. 程序中存在过分耗时且不可能完成的操做(仍是程序的问题),例如discuz x 1.5的附件下载功能: source/module/forum/forum_attachement.php中的定义
function getremotefile($file) { global $_G; @set_time_limit(0); if(!@readfile($_G['setting']['ftp']['attachurl'].'forum/'.$file)) { $ftp = ftpcmd('object'); $tmpfile = @tempnam($_G['setting']['attachdir'], ''); if($ftp->ftp_get($tmpfile, 'forum/'.$file, FTP_BINARY)) { @readfile($tmpfile); @unlink($tmpfile); } else { @unlink($tmpfile); return FALSE; } } return TRUE; }
没有对传入的参数做任何初步检查,并且设置了永不超时,而且使用readfile一次读取超大文件,就可能存在如下问题: A. 以http方式读取远程附件过分耗时
B. FTP没法链接时,如何及时反馈出错误?
C. readfile是一次性读取文件加载到内存中并输出,当文件过大时,内存消耗惊人
根据实验发现采用readfile一次性读取,内存消耗会明显增长,可是CPU的利用率会降低较多。若是采用分段读取的方式,内存消耗会稍微降低,而CPU占用却会明显上升。
对discuz x 1.5的这个bug较好解决方法就是后台从新正确设置远程附件参数。
如下是我逐步整理的故障排除步骤:
1. 获得占用cpu资源过多的php-cgi进程的pid(进程id), 使用top命令便可,以下图:
通过上图,咱们发现,有两个php-cgi进程的cpu资源占用率太高,pid分别是10059,11570,这通常都是程序优化不够形成,如何定位问题的php程序位置?
2. 找出进程所使用的文件
/proc/文件系统保存在内存中,主要保存系统的状态,关键配置等等,而/proc/目录下有不少数字目录,就是进程的相关信息,以下图,咱们看看进程10059正在使用哪些文件?
显然,使用了/home/tmp/sess_*文件,这明显是PHP的session文件, 咱们查看这个session文件的内容为:view_time|123333312412
到这里,咱们已经能够怀疑是因为php程序写入一个叫view_time的session项而引发, 那么剩余的事件就是检查包含view_time的全部php文件,而后修改之(好比改用COOKIE),这实话, 这个view_time并不是敏感数据,仅仅记录用户最后访问时间,实在不必使用代价巨大的session, 而应该使用cookie。
3. 找出有问题的程序,修改之
使用vi编辑如下shell程序(假设网站程序位于/www目录下)
#!/bin/bash find /www/ -name "*.php" > list.txt f=`cat ./list.txt` for n in $f do r=`egrep 'view_time' $n` if [ ! "$r" = "" ] ; then echo $n fi done
运行这个shell程序,将输出包含有view_time的文件, 对记事狗微博系统,产生的问题位于modules/topic.mod.class文件中
http://blog.csdn.net/turkeyzhou/article/details/6709953
http://www.cnblogs.com/cute/archive/2011/04/20/2022280.html
最近对个人本本(4核8线程)用top命令看系统情况出现了CPU利用率超过200%的状况,很是诧异,查了下相关资料,把这个问题弄清楚了。 首先来分析下CPU Load
load average: 0.09, 0.05, 0.01
分别是1分钟、5分钟、15分钟的平均Load。 Load这个东西怎么理解呢,就像一条马路,有N个车道,若是N个进程进入车道,那么正好一人一个,再多一辆车就占不到车道,要等有一个车空出车道。 在CPU中能够理解为CPU能够并行处理的任务数,那么就是“CPU个数 * 核数”,若是CPU Load = CPU个数 * 核数 那么就是说CPU正好满负载,再多一点,可能就要出问题了,有任务不能被及时分配处理器,那么保证性能的话,最好是小于CPU个数 * 核数 *0.7。
查看CPU核数能够经过:grep ‘model name’ /proc/cpuinfo
那么以哪一个平均值为准呢?若是1分钟平均出现大于CPU个数 * 核数的状况,还不用担忧,若是5分钟平均也是,那就要警戒了,15分钟平均也是这样,就要分析哪里出问题了,防范于未然 CPU利用率超过100%的问题,也是差很少,top命令应该是把每一个核的CPU占用率加起来,算一个和,因而多核状况下会出现超过100%。
另外Context Switch Rate也是个很是值得注意的值,由于线程间切换的代价也是很是高的。
引用一个公式:Context Switch Rate = Interrupt Rate + TPS* N
对于一个多线程的程序,我以为准备一个控制线程来调度任务是很是必要的,省得线程过于高并发,致使资源的争用和线程切换带来性能问题,最好控制并发的线程数基本等于CPU的总核数,减小这个N,得到更好的处理器性能。