如何解决限制通过 systemd 管理的进程的交换使用
我正在尝试使用 Ubuntu 18.04 的 doc 中提到的 MemorySwapMax
来限制进程的交换使用。
环境
ubuntu@vrni-platform:/usr/lib/systemd/system$ uname -a
Linux vrni-platform 4.15.0-143-generic #147-Ubuntu SMP Wed Apr 14 16:10:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
ubuntu@vrni-platform:/usr/lib/systemd/system$ systemctl --version
systemd 237
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
我的 systemd 单元文件如下所示
[Unit]
Description=My service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=support
MemoryMax=2000M
KillMode=process
MemoryAccounting=true
OOMScoreAdjust=1000
MemorySwapMax=0
ExecStart=/usr/bin/java -cp /home/support -XX:NativeMemoryTracking=summary -Xmx10000m MemoryConsumer 100 200 1
我尝试通过为 MemorySwapMax
指定 0 来禁用此进程的交换。但 systemd 中似乎有一些 issue 已在 systemd 239 中修复。
所以我也尝试设置 MemorySwapMax=1M
。但这似乎也没有限制此 systemd 服务的交换内存使用。
MemorySwapMax
的文档说明了这一点
This setting is supported only if the unified control group hierarchy is used and disables MemoryLimit=.
如本 answer 中所述,我可以看到在我的设置中启用了 cgroup v2。
ubuntu@vrni-platform:/tmp/debraj$ sudo mount -t cgroup2 none /tmp/debraj
ubuntu@vrni-platform:/tmp/debraj$ ls -l /tmp/debraj/
total 0
-r--r--r-- 1 root root 0 Jul 2 17:13 cgroup.controllers
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.max.depth
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.max.descendants
-rw-r--r-- 1 root root 0 Jun 30 14:42 cgroup.procs
-r--r--r-- 1 root root 0 Jul 2 17:13 cgroup.stat
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.subtree_control
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.threads
drwxr-xr-x 2 root root 0 Jun 30 14:42 init.scope
drwxr-xr-x 87 root root 0 Jul 2 15:05 system.slice
drwxr-xr-x 7 root root 0 Jun 30 15:22 user.slice
ubuntu@vrni-platform:/tmp/debraj$ sudo umount /tmp/debraj
MemoryConsumer.java 如下所示
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class MemoryConsumer {
public static void main(String[] args) throws InterruptedException,IOException {
int size = Integer.parseInt(args[0]);
int count = Integer.parseInt(args[1]);
int sleepMs = Integer.parseInt(args[2]);
List<ByteBuffer> list1 = new ArrayList<>();
List<byte[]> list2 = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i=0; i<count; i++) {
list1.add(ByteBuffer.allocateDirect(size*1024*1024));
//list2.add(new byte [size*1024*1024]);
long end = System.currentTimeMillis();
System.out.println("Allocated memory " + (i*size) + " MB\n" + (end-start) + " ms");
Thread.sleep(sleepMs);
}
}
}
有人可以建议这里出了什么问题吗?
解决方法
这已在 systemd 邮件列表中得到解答。
重新发布相关部分。
看起来您的 Ubuntu 版本正在使用“混合”cgroup 模式
默认。 Cgroup v2 确实在您的内核中启用,但没有
一定
in use – 在混合模式下,systemd 仍然在 v1 模式下挂载所有资源控制器(cpu、内存等),并且只设置自己的
v2 树中的进程跟踪。请参阅findmnt
。
您可以使用 systemd.unified_cgroup_hierarchy=1 内核启动 将所有内容切换到 cgroups v2 的选项,但如果您正在使用 容器软件(docker、podman)确保这些是 cgroups v2 兼容。
你好黛布拉。
2021 年 7 月 8 日星期四下午 05:10:44 +0530,Debraj Manna 写道:
Linux vrni-platform 4.15.0-143-generic #147-Ubuntu SMP Wed Apr 14 16:10:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux [...] GRUB_CMDLINE_LINUX="audit=1 rootdelay=180 nousb net.ifnames=0 biosdevname=0 fsck.mode=强制 fsck.repair=yes ipv6.disable=1 systemd.unified_cgroup_hierarchy=1"
即使进行了这些更改,MemorySwapMax 也不会生效。
还需要加上swapaccount=1,swap记账是通过 仅自内核 v5.8 起默认。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。