gpt4 book ai didi

unix - 如何在 Golang 中为进程设置内存限制

转载 作者:IT王子 更新时间:2023-10-29 00:54:28 28 4
gpt4 key购买 nike

我使用系统调用 prlimit 来设置进程的资源限制,它可以限制 CPU 时间,但是当测试内存使用时,我遇到了问题。

package sandbox

import (
"syscall"
"unsafe"
)

func prLimit(pid int, limit uintptr, rlimit *syscall.Rlimit) error {
_, _, errno := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, uintptr(pid), limit, uintptr(unsafe.Pointer(rlimit)), 0, 0, 0)
var err error
if errno != 0 {
err = errno
return err
} else {
return nil
}
}

这是我的测试。

func TestMemoryLimit(t *testing.T) {
proc, err := os.StartProcess("test/memo", []string{"memo"}, &os.ProcAttr{})
if err != nil {
panic(err)
}
defer proc.Kill()
var rlimit syscall.Rlimit
rlimit.Cur = 10
rlimit.Max = 10 + 1024
prLimit(proc.Pid, syscall.RLIMIT_DATA, &rlimit)
status, err := proc.Wait()
if status.Success() {
t.Fatal("memory test failed")
}
}

这是备忘录:

package main

func main() {
var a [10000][]int
for i := 0; i < 1000; i++ {
a[i] = make([]int, 1024)
}
}

我制作了大量的内存并且只为内存设置了 10 个字节,但它不会以任何方式发出段错误信号。

最佳答案

RLIMIT_DATA 描述进程数据段的最大大小。传统上,分配内存的程序通过调用 brk() 从操作系统分配内存来扩大数据段。

Go 不使用这种方法。相反,它使用 mmap() 系统调用的变体来请求地址空间中任意位置的内存区域。这比基于 brk() 的方法灵活得多,因为您可以使用 munmap() 释放任意内存区域,而 brk()基于方法只能从数据段末尾释放内存。

结果是 RLIMIT_DATA 在控制进程使用的内存量方面无效。尝试改用 RLIMIT_AS,但请注意,此限制还包括您用于文件映射的地址空间,尤其是在共享库的情况下。

关于unix - 如何在 Golang 中为进程设置内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24522692/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com