我的 Ubuntu 19.04 系统上有一个 Python 进程,它似乎并不缺乏内存,但运行速度比我预期的慢很多。该系统具有 96 GB RAM 和 96 GB 交换空间。此进程的计算量很大,并且是系统上唯一占用大量内存的进程。
top
看起来像这样:
top - 04:26:15 up 18 days, 6:26, 1 user, load average: 1.00, 1.02, 1.23
Tasks: 328 total, 1 running, 327 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.7 us, 0.6 sy, 0.0 ni, 96.1 id, 2.5 wa, 0.0 hi, 0.0 si, 0.0 st
GiB Mem : 94.3 total, 0.5 free, 86.1 used, 7.8 buff/cache
GiB Swap: 104.0 total, 97.5 free, 6.5 used. 7.4 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15182 baccala 20 0 117.6g 85.2g 3736 D 20.3 90.3 32:06.77 python2
我真正不明白的是这与strace
告诉我的内容如何相吻合:
baccala@blade1:~/helium$ timeout 10s strace -cw -p 15182
strace: Process 15182 attached
strace: Process 15182 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.055781 86 645 brk
------ ----------- ----------- --------- --------- ----------------
100.00 0.055781 645 total
由于十多秒的时间间隔,系统调用只花费了 55 毫秒,为什么 CPU 利用率只有 20% 且处于“D”状态?
我读到这篇文章就像top
告诉我该程序在内核中花费了大量时间,但strace
告诉我相反的情况。另外,系统几乎没有触及它的交换空间,而且我仍然有几GB的缓冲/缓存,所以它看起来不应该内存不足,即使它使用了很多。
该进程以 100% CPU 运行,直到达到约 80 GB 驻留集大小,然后开始执行此操作。另外,程序启动时我没有配置交换区,但在swapon
发现它可能会耗尽 RAM 后添加了它。
有人能解释一下这是怎么回事吗?
更新
我现在确信这个过程缺乏内存。我没有考虑的是,strace
只显示系统调用中的延迟,但不显示页面错误期间的延迟。以及过程是交换,如图iotop
:
TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
15182 be/4 baccala 1409.08 K/s 0.00 B/s 92.57 % 0.00 % python2
15182 be/4 baccala 1649.00 K/s 0.00 B/s 91.62 % 0.00 % python2
15182 be/4 baccala 1245.74 K/s 0.00 B/s 94.78 % 0.00 % python2
15182 be/4 baccala 1904.57 K/s 0.00 B/s 90.60 % 0.00 % python2
15182 be/4 baccala 1904.63 K/s 0.00 B/s 88.55 % 0.00 % python2
我仍然不明白的是,为什么top
当 的RES
字段仍然比机器的可用 RAM 还少 16 GB,并且 仍然列出了 10 GB时,这种行为就开始了buff/cache
。我仍然不明白 Linux 是如何管理内存的。