身为一个工程师,不管你写的是前端、后端、全端还是什么端,一定多少用过htop,就算真的没用过也会听同事说过。htop是一个process manager,他可以让你看到执行中的process、系统资源的使用量,也可以让你轻松kill掉任何一个process,总之,你想得到的功能统统都有~

虽然大家都说htop很好用,但许多人打开htop也只看得懂CPU、Mem、PID、Command这些简单的字段,对于Load average、NI、State、SHR就没那么熟悉

不过htop都帮你列出来了,看不懂好像又有点可惜对吧!所以这篇文章要跟大家钜细弥遗的介绍htop每个字段的意义,也许哪天有需要时就能派上用场呢!

CPU

首先来说说最重要的CPU,在htop最上方会列出各CPU的使用率,值得注意的是这边显示的是CPU的逻辑核心数,譬如说你的电脑有四核心八线程,意思是同时可以执行八个thread,那这边就会显示八个CPU哦~

1_Y9NM4kTtBEppLelmeQ4Azg.webp

另外不知道有没有人发现这个使用率的bar包含了红色跟绿色,有时甚至还会有蓝色,那其实是有意义的哦:

  • 红色代表的是kernel thread占用的CPU,像是系统需要自动做process scheduling、memory management等等,是整个系统中最重要、优先权也最高的任务

  • 绿色代表的是normal priority thread,排程的优先权比kernel thread低一些,一般来说使用者执行的程序如果没有特别调优先权的话,都会归在这一类

  • 蓝色的话就是low priority thread,因为优先权比较低,分配到的CPU自然也比较少,适合「我ok,你先跑」那类比较无关紧要的process,如果CPU已经被操到快不行了,或是memory真的不够用了,第一个杀掉的也是这类process

Memory & Swap

1_SdWoFDelfkaJvmdmOjzqTQ.webp

紧接在CPU下面的是memory跟swap的使用量,memory这边应该大家都看得懂,值得一提的是他的颜色也是有意义的:

  • 绿色指的是被process占用的內存,譬如说你开的浏览器、VSCode、终端机等等程序,还有正在执行的htop都算是这一类

  • 蓝色则是buffer pages,他是用来储存一些metadata。譬如说当你第一次执行ls -l时系统会去硬盘捞看这个文件夹有哪些档案、每个档案的权限等等,然后帮你存在buffer pages,当你短时间内再执行ls -l时就不用再进入硬盘(因为硬盘很慢),直接从buffer拿即可

  • 橘色的cache pages跟buffer很像,只不过buffer存的是metadata,而cache存的是档案内容。像你第一次下cat index.js时就会把内容读取到cache pages,如果你cat之后发现代码太长,决定先看前十行就好了,那再下head -n 10 index.js就会从cache pages直接读取

这也代表说內存使用量并非越低越好,毕竟闲在那边也没啥用,不如让系统把闲置的部分拿去当buffer跟cache,读取时能不碰硬盘就不碰硬碟,才可以让程序执行得更快

所以千万不要相信什么「内存清理大师」可以帮你提升性能,说真的没变慢就不错了,随便把buffer跟cache都清掉了只会加重系统负担。內存管理就交给系统来,十之八九都可以管理得还不错

1_SdWoFDelfkaJvmdmOjzqTQ.webp

而swap的部分虽然上图完全没用到,但还是解释一下:swap的机制跟刚刚提到的cache & buffer正好相反,万一你实在开了太多程序,而且每个程序都跟chrome一样狂吃猛吃,导致memory快要不够了

那系统就会把內存里面一些东西swap到硬盘上,等真的需要那些东西时再从硬盘拿回来。虽然这样做看似有更多內存可以用,但代价就是程序速度会慢上许多,因为硬盘实在是太慢了

Load Average

接着来看看屏幕右上方那堆神奇的数字

首先Tasks字段的488,1994 thr;3 running代表的是目前总共有488的process、1994个thread,其中3个thread正在执行(这数字最大就是你的逻辑核心数)

1_WN1L1_kbk8jK2fuwgYwlXw.webp

而Load Average(LA)是用来判断断目前系统有多繁忙,三个数字代表的是系统在最近1分钟、5分钟、15分钟内,平均有多少个thread需要CPU

以上图来说,近一分钟内平均有5.9个thread需要使用CPU进行运算,但无奈我只有4个逻辑核心,所以CPU是忙到翻过来,而最近十五分钟的LA是3.49,其实也算是高了

一般来说电脑完全没在用时LA会低于1,而平常在上网、听音乐、做简报则是会介于1到2之间

所以如果觉得自己写的程序跑很慢,不妨先看看LA确认瓶颈是不是在CPU,如果LA很低但程序却慢得夸张,那很可能程序并没有善用多核心,或是瓶颈卡在硬盘跟网络IO;如果LA已经很高了但还是觉得太慢,那就只能改善算法、或是换更快的CPU了

PID/USER

上面讲完之后来看看下面这一大块,这部分每个row都是一个process,而PID就是每个process的ID

1_pwf3sNWA2shXjgwhK4Rysg.webp

那知道PID之后可以干嘛呢?其实他的用途挺多的,譬如说你可以用kill -KILL <pid>来杀掉某个process;或是使用kill -STOP来暂停process再用kill -CONT让他继续执行(这超好用👍,但好像很多人都不知道)

而USER字段没什么好解释的,就是把这个process跑起来的人。不管程序是谁写的,只要是我把他跑起来,USER那栏就会显示我的名字

PRI & NI

接下来的Priority跟Nice两个都是跟优先权有关的指标,注意数字越小表示优先权越高,也就可以分配到越多CPU时间

1_Y1dau0jk7lDXC0hHI5gp_w.webp

其中PRI是由系统帮你决定的,无法自行修改,像上图mdbulkimport的PRI值是17,而ping 8.8.8.8则是24,代表系统认为mdbulkimport比ping来得重要

注:mdbulkimport是mac spotlight功能的一部分

而nice值的部分预设是0,可以用renice -n 19 -p <pid>调整到最低优先权19,想要调高的话最高也可以调到-20

虽然nice值可以随自己高兴调高调低,但系统不见得都会听你的。有的系统比较友善会愿意参考你设的nice值,但也有一些只看PRI系统根本不在乎nice,你设你的我排我的,所以不要太期待提高优先权可以为性能带来多大的变化,想要提升性能还是乖乖把程式写好比较重要~

VIRT/RES/SHR

这三个数字都是跟內存有关的,分别代表Virtual memory、Resident跟Shared memory

1_gjN0MDsr5kg9hgpQMtVzTQ.webp

irtual memory的概念比较复杂一点,基本上你可以把他想成process可以存取到的memory总和。譬如说head -n index.js内部运作的方式是先把index.js打开,然后读取前十行

虽然他只读取前十行,但head process已经把档案打开了,他其实有权限access到整个档案的内容(只是它没有这么做),所以virtual memory会把整个档案的大小算进去

而Resident正好相反,他指的是物理上你到底占用了多少內存。以同样的例子来说,若你只读取前十行,那系统就只把前十行从硬盘读进內存,RES也就只算那十行

因此在htop里面RES一定会小于VIRT(如下图),而且通常是远小于,因为VIRT会把一堆哩哩叩叩的东西都算进去,所以就算看到VIRT很肥也完全不用担心

1_gjN0MDsr5kg9hgpQMtVzTQ.webp

而Shared memory的话顾名思义就是可以跟别人分享的memory,像程序执行时很常会用的glibc,或是在读取read-only档案时,这些东西都只需要读进內存一次就可以了,所以就会被算进SHR里面

虽说能跟其他process共享內存是好事,但这种事也强求不来,所以一般我都只看RES,很少在管SHR是多少

State

1_i6NnubhankPL-nee4F_iTQ.webp

接着来看这小小一个S,代表的是process的state,比较常见的有以下几个

  • R:意思是process正在跑或是在running queue里等待CPU排程

如果你的程序长时间处于R状态但还是跑很慢,代表可能是算法太慢了,或是CPU实在太忙一直把你丢在queue里面,可以再透过CPU%来确认是哪个问题

  • S:目前正在睡觉,有事做才会醒来

通常定时执行的、要使用者互动的程式如ping跟VSCode很常会处于S状态(上图),毕竟ping一秒只送一个封包,但现今的CPU一秒可以跑十亿个cycle,所以CPU当然是送出封包后就马上把你踢到旁边去睡觉,等一秒后你睡醒了再回来

VSCode的话是因为你总不可能一秒打十亿个字吧,所以没事做的时候他会马上被CPU踢出去,等你打字了他再被叫回来动一下,然后马上又被踢出去

  • D:这个也是在睡觉,只不过等待的一定是IO,譬如说读取档案、写入数据库等等

如果你的process长时间处于D状态,代表IO所占的时间比较多,三不五时就被CPU踢出去睡觉。因此想改善性能也要从IO着手,譬如用redis做缓存或是换SSD等等,若只是单纯更换程序语言或是升级CPU可能没什么效果

CPU%/MEM%

1_lcjZ888wF35qUuYn_72B-Q.webp

CPU%意思是你在这段时间平均用了几颗CPU,因为htop预设3秒更新一次,假如前1.5秒你用了一颗,后1.5都没用,那平均就是50%;如果你这三秒用好用满四个核心,那就是漂亮的400%(上图Rust编译器的其中一个process就有用到331%)

因为CPU%是很短期的数据,所以当你突然觉得电脑当当的快不行时,直接看CPU%就可以知道是谁在作怪,然后看是要用signal把他暂停还是干脆直接杀掉

MEM%也很类似,就是使用內存的比例,要注意的是他是用RES来做计算,所以如果电脑配有4GB的內存、某个process的RES是1GB,那他就是用掉实体內存的25%

Time+

最后要来说说Time+,这个时间很有意思,他代表的并不是程序从启动到现在总共经过了多久,而是这个程序总共占用了多少CPU Time

1_OKEwTc1DML1DnsUVhOowBw.webp

譬如说上图我在编译Rust时,虽然我才刚跑十秒而已,但CPU Time已经有28秒,代表说这个process在十秒内平均使用了2.8颗CPU,也就是平均的CPU%是280%左右

相反的如果像ping 8.8.8.8这种几乎不需要CPU运算的process(就只是把封包送出去而已),那即便跑了十多分钟,占用的CPU Time也不过12秒而已,平均起来的CPU%大概是2%左右

1_z_wCrLymdo89Oe-6x9A1LQ.webp

因此如果想知道长期而言哪个程序最占CPU的话,就看Time+的数值;如果是想看短期、目前正在暴冲的程序,那就是看先前提到的CPU%

总结

今天介绍了怎么用htop看系统的负载状态、各种內存使用量、以及长短期的CPU使用率,看到这我想大家都累了,一下子信息量太大说不定也忘得差不多了XD

但也没关系,看完脑袋中有个概念就好了,先把文章收藏起来,哪天发现又看不太懂htop时,再回来当技术文件翻一下也可以哦~