假设我创建了一个 cgroup,并为该 cgroup 附加了 200MB 的内存限制。然后,我在 cgroup 内运行一个内存密集型进程,它用完了 200MB 的限制。
当进程运行时,是否可以降低进程的内存消耗?那么当进程已经运行并使用 200MB 时,我可以设置 100MB 的限制吗?如果是这样,内核释放 cgroup 正在使用的 100MB 内存的速度有多快,如果进程尝试访问该内存,会发生什么情况?
答案1
是的,取决于您所说的“分配”是什么意思。您可以减少或增加数量身体的进程可以使用的内存。
正在使用的内存包括:
- 映射到进程的磁盘映像(例如共享库、可执行文件)
- 由 IO 缓存层缓存的磁盘页面
- 匿名内存可能受交换支持,也可能不支持。
当减少 cgroup 时,memory.limit_in_bytes
系统将从磁盘缓存和磁盘映像(例如可执行文件)中丢弃页面,因为如果需要,这些页面始终可以重新加载。
如果启用了交换,它还可以调出匿名内存。
为您的进程创建一个 cgroup 并设置限制
# Create a cgroup
mkdir /sys/fs/cgroup/memory/my_cgroup
# Add the process to it
echo $PID > /sys/fs/cgroup/memory/my_cgroup/cgroup.procs
# Set the limit to 40MB
echo $((40 * 1024 * 1024)) > /sys/fs/cgroup/memory/my_cgroup/memory.limit_in_bytes
系统会立即进行交换,直到低于限制,并且它将继续这样做以使进程保持在限制之下。
如果内核最初不可能将进程或组置于限制之下(因为某些内存无法交换,例如,如果您没有任何交换,或者某些内核页面可能不可交换),则会发生错误,并且限制不会改变。
如果将来某个时候无法执行此操作,OOM 杀手将终止该进程(或其子进程之一)。
您可以使用该oom_control
密钥来暂停组中的进程,但随后您必须自己解决问题,方法是提高限制或终止一个或多个进程。
更多信息
还有一把memory.soft_limit_in_bytes
钥匙。这不会调用 oom Killer,而是在系统面临内存压力时使用它来确定首先换出哪些进程(也可能在其他时间)。
从流程或组内部
可以通过对内存限制进行编码来查询当前使用情况以及硬限制和软限制,从而使进程了解内存限制。然后,他们可以采取措施避免违反限制,例如通过避免:分配内存、创建子进程或接受新连接;或者通过终止现有连接等方式减少使用。
进程可以使用 cgroups 通知 API 订阅通知。
也可以看看
内核文档位于:
答案2
不,一旦正在运行的程序成功分配了内存,您就无法将其拿走。
另请注意,对进程使用的内存进行限制,如果超出限制,将导致内核杀死 cgroup 中使用内存最多的进程;它不会导致程序内的内存分配失败。