$ systemctl status machine.slice
● machine.slice - Virtual Machine and Container Slice
Loaded: loaded (/usr/lib/systemd/system/machine.slice; static; vendor preset: disabled)
Active: active since Wed 2018-06-13 08:45:07 BST; 1 day 15h ago
Docs: man:systemd.special(7)
Tasks: 0
Memory: 717.0M
CGroup: /machine.slice
$ cd /sys/fs/cgroup/memory/machine.slice
$ cat memory.usage_in_bytes
751915008
$ cat tasks
$ cat cgroup.procs
$
machine.slice
即使 cgroup 中没有进程/线程,但仍使用 717MB,这意味着什么?这是内核错误吗?
我可以通过使用 virt-manager 启动虚拟机然后停止它来重现这一点。如果我重复这个循环,结果大致相同 - 即系统似乎没有泄漏这数百兆字节。
软件版本
$ uname -r
4.16.14-300.fc28.x86_64
$ rpm -q systemd libvirt-daemon
systemd-238-8.git0e0aa59.fc28.x86_64
libvirt-daemon-4.1.0-2.fc28.x86_64
答案1
这不是一个错误。显然,cgroup 内存的统计包括进程使用的磁盘缓存页面。如果需要,您可以使用 请求丢弃属于 cgroup 的缓存页面force_empty
。
您可能想知道多个 cgroup 使用的缓存页面。 cgroup-v2.rst
(我正在使用的版本的后继版本)告诉我们:
内存区域被实例化它的 cgroup 占用,并保持被 cgroup 占用,直到该区域被释放。将进程迁移到不同的 cgroup 不会将其在前一个 cgroup 中实例化的内存使用量移动到新的 cgroup。
内存区域可以由属于不同 cgroup 的进程使用。该区域将被计入哪个 cgroup 是不确定的;然而,随着时间的推移,内存区域很可能最终出现在一个有足够内存空间以避免高回收压力的 cgroup 中。
cgroup-v1/memory.txt
还说“页面专门链接到 per-memcg LRU”,因此它的工作原理可能与上面的描述类似。这份文件更难依赖,因为它以免责声明开头,称它“已经过时了,需要完全重写”。
即force_empty
请求立即删除所有这些页面。如果有另一个 cgroup 也想使用它们,则必须再次从磁盘读入它们。