htop使用技巧:从CPU到内存,深入了解系统资源监控

2024-05-10 15:18:14 浏览数 (2)

CPU

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

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

  • 红色代表的是kernel thread(内核线程)占用的 CPU,像是系统需要自动做 process scheduling(进程调度)、memory management(内存管理)等等,是整个系统中最重要、优先权也最高的任务
  • 绿色代表的是normal priority thread(普通优先级线程),线程的优先权比 kernel thread 低一些,一般来说用户执行的程序如果没有特别调优先权的话,都会归在这一类
  • 蓝色的话就是low priority thread(低优先级线程),因为优先级较低,分配到的 CPU 自然也比较少,适合「我 ok,你先跑」那些比较无关紧要的任务,如果 CPU 利用率已经特别高了了,或是内存真的不够用了,第一个杀掉的也是这类进程。

Memory & Swap

紧接在 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 都清掉了只会让系统负担加重。内存管理就交给系统来,十之八九都可以管理得还不错

而 swap 的部分虽然上图完全没有用到,但还是解释一下:swap 的机制跟刚刚提到的 cache & buffer 正好相反,万一你实在开太多程序,而且每个程序都跟 chrome 一样狂吃猛吃,导致 memory 快要不够了,那系统就会把内存里面一些东西 swap 到硬盘上,等真的需要那些东西时再从硬盘拿回来。虽然这样做看似有更多的内存可以用,但代价就是程序速度会慢上许多,因为硬盘实在是太慢了

Load Average

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

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

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

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

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

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

PRI & NI

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

其中 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(共享内存)

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

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

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

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

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

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

State

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

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

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

  • S:目前正处于睡眠状态,有事做才会醒来

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

对于 VSCode 来说,因为你不可能每秒打十亿个字,所以当你不打字的时候,它会被 CPU 立即踢出去,等你开始打字时再被唤醒,然后立即又被踢出去。

  • D: 这也是在睡眠状态,但等待的一定是 I/O 操作,比如读取文件、写入数据等

如果你的进程长时间处于 D 状态,这意味着 I/O 占用的时间较多,时不时地被 CPU 踢出去睡觉。因此,如果想要改善性能,也需要从 I/O 入手,比如使用 Redis 进行缓存或者更换 SSD 等,单纯更换编程语言或升级 CPU 可能不会有太大效果。

CPU%/MEM%

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

由于 CPU% 是一个非常短期的数据,所以当你突然觉得电脑运行缓慢时,直接查看 CPU% 就可以知道是哪个进程在占用资源,然后决定是发送信号暂停它还是直接杀掉它。

MEM% 也很类似,它表示的是使用内存的比例,需要注意的是它使用 RES(常驻内存集)来计算,所以如果电脑有 4GB 内存,某个进程的 RES 是 1GB,那么它就占用了物理内存的 25%。

Time

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

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

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

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

总结

今天介绍了如何使用 htop 查看系统的负载状态、各种内存使用量以及长短期的 CPU 使用率。看到这里,我想大家都累了,一下子信息量太大可能也忘得差不多了,但没关系,只要在脑海中有个概念就好,先把文章收藏起来,哪天发现又看不懂 htop 时,再回来当作技术文档翻阅一下也可以哦~

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

0 人点赞