答案1
使用字节数
为了提高效率,与其他内核组件一样,内存 cgroup 使用一些优化来避免不必要的缓存行错误共享。 use_in_bytes 受该方法的影响,不显示内存(和交换)使用量的“准确”值,它是有效访问的模糊值。 (当然,必要的时候,它是同步的。)如果你想知道更准确的内存使用情况,你应该使用memory.stat中的RSS+CACHE(+SWAP)值(参见5.2)。
如果您反复阅读准确的文件,和您已测量系统性能受到 cpu 使用率的限制,您可以考虑对 memory_usage 进行采样。
我不知道它是如何工作的。然而,作为 LWN.net 阅读器,这听起来类似于这样的情况:可以存在多个计数器,这些计数器保留在使用它们的本地位置,并且以某种方式读取 use_in_bytes 不会强制立即同步和汇总这些计数器。
多年来,内核开发人员越来越多地使用每个 CPU 的数据,以尽量减少内存争用及其相关的性能损失。作为一个简单的例子,考虑由块层维护的磁盘操作统计数据。为每个磁盘操作增加全局计数器将导致相关的高速缓存行在处理器之间不断地跳动;磁盘操作足够频繁,性能成本是可以衡量的。因此每个CPU在本地维护自己的一组计数器;它永远不需要与任何其他 CPU 竞争来增加其中一个计数器的值。当需要总计数时,所有每个 CPU 的计数器都会相加。鉴于计数器的查询次数远远少于修改次数,以每个 CPU 的形式存储它们可以显着提高性能。
--https://lwn.net/Articles/258238/
如果您有一个小型系统 - 没有大量的 cpu,也没有维护大量的 cgroup - 开销听起来不是很大。在 cpu 之间反弹几条缓存行的成本并不高。但如果您是 Google 并且在系统上运行数千个容器,或者如果您的系统拥有数千个 cpu,那么效率可能会很有用。
答案2
我认为在两种情况下查看进程时,我发现内存使用情况不一致。
场景1:直接在 cgroup 下创建的进程 显示的内存使用情况看起来是正确的。
# cgexec -g memory:mem128 sleep 30 &
[2] 18339
# cat /sys/fs/cgroup/memory/mem128/memory.usage_in_bytes
135168
场景2:单独创建进程,然后分配到一个cgroup。显示的内存使用情况不正确。 36864 似乎不正确。有时也显示0。为什么这与上面所示的场景 1 不同?
# sleep 90 &
[2] 18937
# cgclassify -g memory:/mem128 18937
# cat /sys/fs/cgroup/memory/mem128/memory.usage_in_bytes
36864