顶部命令 – 进程的CPU不加起来

我了解top命令( 6.5%us17.2%sy0.0%ni等)报告的各种CPU使用情况,但是为什么每个进程的总CPU百分比不能累加到任何一个Cpu(s)值? 例如,java进程下面占用了77.5%的CPU,而Cpu(s)说76.0%仍然是空闲的。 为什么是这样? 这是在一个单一的核心系统。

 top - 05:53:27 up 32 min, 2 users, load average: 0.16, 0.29, 0.34 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie Cpu(s): 6.5%us, 17.2%sy, 0.0%ni, 76.0%id, 0.0%wa, 0.0%hi, 0.3%si, 0.0%st Mem: 1758616k total, 643432k used, 1115184k free, 12224k buffers Swap: 917500k total, 0k used, 917500k free, 304608k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1307 tomcat 20 0 683m 287m 9528 S 77.5 16.8 10:54.99 java 1571 ec2-user 20 0 2592 1096 872 R 1.0 0.1 0:08.61 top 1 root 20 0 2892 1364 1168 S 0.0 0.1 0:00.28 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 

编辑 :原来这是一个双核心系统。 在top命令启动时按下1后,这里是更新的输出:

 top - 06:10:21 up 49 min, 2 users, load average: 0.28, 0.37, 0.34 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie Cpu0 : 9.9%us, 19.7%sy, 0.0%ni, 69.0%id, 0.0%wa, 0.0%hi, 1.4%si, 0.0%st Cpu1 : 5.0%us, 10.0%sy, 0.0%ni, 85.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 1758616k total, 677548k used, 1081068k free, 13296k buffers Swap: 917500k total, 0k used, 917500k free, 305732k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1307 tomcat 20 0 683m 318m 9528 S 68.0 18.6 17:23.53 java 1 root 20 0 2892 1364 1168 S 0.0 0.1 0:00.28 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.91 ksoftirqd/0 4 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 

您正在比较的这两个信息将不匹配,因为它们是从不同的文件收集的。 即使顶部显示在同一个terminal的信息,他们不是从同一个来源收集。

我只是在顶部运行strace(以批处理模式运行)。 这是显示系统CPU信息的地方。

 16:04:04.081092 open("/proc/stat", O_RDONLY) = 6 <0.000022> 16:04:04.081154 lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 <0.000015> 16:04:04.081211 lstat("/proc/stat", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013> 16:04:04.081267 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013> 16:04:04.081334 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013> 16:04:04.081385 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f699ace2000 <0.000016> 16:04:04.081440 lseek(6, 0, SEEK_SET) = 0 <0.000013> 16:04:04.081494 read(6, "cpu 302573 6910 83103 10092403 "..., 1024) = 1024 <0.000070> 16:04:04.081656 write(1, "%Cpu(s): 2.9 us, 0.8 sy, 0.1 "..., 80) = 80 <0.000034> 16:04:04.081763 write(1, "KiB Mem: 8048484 total, 41402"..., 73) = 73 <0.000035> 16:04:04.081858 write(1, "KiB Swap: 8060924 total, "..., 72) = 72 <0.000034> 16:04:04.081940 write(1, "\n", 1) = 1 <0.000026> 

现在,如果您看到/proc/stat ,它会显示系统的所有CPU。 顶部也知道,因为在打开/ proc / stat之前,它会打开sys文件系统。

 16:04:03.367339 open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3 <0.000027> 16:04:03.367408 read(3, "0-7\n", 8192) = 4 <0.000019> 16:04:03.367464 close(3) = 0 <0.000015> 

现在,当收集单独的进程信息时,它会从/proc/pid/statm/proc/pid/stat文件中获取。 (用pidreplace,实际的pid)。

正如您所看到的, /proc/stat所有 CPU的系统范围信息,pid的单个proc文件是它们的特定pid-only信息。

所以,他们不会匹配。

采样是CPU使用的top措施,可能会出错。

最好的解释方法是这样的:设想一个工厂每小时只能生产一辆汽车。 假设你决定抽样工厂生产汽车的速度。 您在5:59开始采样,并在7:01停止采样。 你看到两辆汽车生产,一个在6:00,一个在7:00。 你抽样了62分钟,生产了2辆车。 因此,你计算出工厂生产的汽车在其额定容量的200%左右。

另外,由于top不提供一组单个系统状态的测量结果,而是一组独立的测量结果,每个都受自己的一套条件的影响,所以无法比较top值。

例如,可以使用与每个进程值完全不同的机制来计算每个CPU的值。 每个CPU的值可以指数衰减,而每个进程的值可以是两个总和之间的差值。 所以他们可以反映相同types的东西的测量,但使用完全不同的方法。