Cgroups

限制所有 X 應用程序的 CPU 和記憶體消耗

  • October 21, 2019

我想保留少量的 cpu 和記憶體,以便在緊急情況下能夠創建 tty 會話並終止佔用記憶體的 X 應用程序。cgroups提供了這個功能。如何自動將我所有的 X 應用程序放入 cgroup 中?

我使用的是 Debian,所以解決方案是基於systemdcgroup 實現的。

第一步是檢查 cgroups 層次結構:

> systemd-cgls
-.slice
├─user.slice
│ └─user-1000.slice
│   ├─user@1000.service
.....
│   └─session-2.scope
│     ├─1376 lightdm --session-child 14 21
│     ├─1400 x-window-manager
.....

systemd自動將 cgroups 分配給終端會話。在 cgroup 層次結構中,我們需要確定其中session-*.scope有 X 應用程序。預設 X 會話範圍號始終相同。

要為範圍內的所有程序設置記憶體限制,請鍵入

> systemctl set-property session-2.scope MemoryLimit=14G

此命令將記憶體限制設置為會話 2,直到重新啟動。

要使此規則永久生效,請執行

> sudo systemctl edit session-2.scope

在文本編輯器類型中

[Scope]
MemoryLimit=14G

並保存。此規則將在重新啟動之間保持不變。其他資源限制可以在同一個文件中設置。


編輯

正如 derobert 所指出的,X 會話範圍號不保證相同。更強大的解決方案是在執行時確定這個數字。

文件/usr/local/bin/resource_limit.sh

#!/bin/bash

for s in $(systemd-cgls --no-pager --user-unit \
          | grep --extended-regexp --only-matching \
             'session-.{1,3}\.scope');do
   systemctl set-property --runtime "$s" MemoryLimit="$1"
done

文件/etc/systemd/system/resource_limit.service

[Unit]
Description=Limit resources
Requires=multi-user.target
After=multi-user.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 5
ExecStart=/usr/local/bin/resource_limit.sh 14G
ExecStop=/usr/local/bin/resource_limit.sh 20G
RemainAfterExit=true

[Install]
WantedBy=graphical.target

將上面的文件複製到您的系統並發出命令

systemctl daemon-reload

在此之後,您可以使用命令設置指定的限制(在本例中為 14G)

systemctl start resource_limit.service

並使用命令取消設置(設置一些更高的限值)

systemctl stop resource_limit.service

為了在重新啟動時自動執行此腳本,請發出命令

systemctl enable resource_limit.service

注1

如果您的 X 會話啟動速度不夠快,您可能需要通過ExecStartPre手動啟用服務來增加服務延遲。

筆記2

將限制添加到user@1000.service(其中 1000 - 是一個 UID)具有稍大的限制是一個好主意。這樣,您將始終擁有可用於系統守護程序的資源。

引用自:https://unix.stackexchange.com/questions/490978