我知道 ulimit,也知道如何限制我明确启动或使用脚本启动的进程的内存。但在本例中,我有一个由 systemd 管理和启动的服务。
当它达到内存使用量的最大值时,我怎样才能限制它的最大内存并终止它(或者更好的是:阻止它分配内存(返回 NULL 到malloc
/ realloc
))?
答案1
这手册页systemd.exec
ulimit
通过系统调用,有一个 LimitXXXX 指令列表和一个方便的表格,将它们与选项进行比较setrlimit()
。
要限制进程的整个地址空间(ulimit -v
),请使用LimitAS=
。否则,要限制堆栈(ulimit -s
)的使用LimitSTACK=
或数据段(ulimit -d
),请使用LimitDATA=
根据setrlimit()
手册页,这些限制将导致分配额外内存失败。如果达到限制并且堆栈需要增长(并且程序没有处理此问题),STACK 和 AS 将使用 sigsegv 终止程序。
答案2
Systemd 支持通过 MemoryLimit 选项限制内存使用量,如下所述:https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html
当允许的最大内存(每个服务)耗尽时,系统处理情况的方式取决于底层 cgroups 实现和 systemd 实现资源控制的方式;我猜测该过程将被终止(通过 OOM 终止程序)。
答案3
对于类似于 ulimit 的限制:
man systemd.exec
...
LimitAS=(like ulimit -v)
...
LimitRSS=(like ulimit -m)
...
答案4
由于 systemd231
您可以指定
[Service]
MemoryHigh=750M
MemoryMax=1G
以上MemoryHigh
进程会严重减慢速度,并且可能会占用内存。如果内存使用量无法控制在限制范围内MemoryMax
,则会在单元内部调用内存不足终止程序。
它需要启用内存核算,例如在系统范围的配置中。
MemoryAccounting=yes