繁体   English   中英

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

[英]How to set memory limit to a process in Golang

我使用 syscall 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 ,但请注意,此限制还包含用于文件映射的地址空间,尤其是在共享库的情况下。

有一个提议Soft memory limit ,可能会在 go 1.18 之后释放

此选项有两种形式:一个名为SetMemoryLimit的新runtime/debug函数和一个GOMEMLIMIT环境变量。 总之,运行时将尝试通过限制堆的大小以及更积极地将内存返回给底层平台来维持这个内存限制。 这包括帮助减轻垃圾收集死亡螺旋的机制。 最后,通过设置 GOGC=off,Go 运行时将始终将堆增长到完整内存限制。

这个新选项使应用程序可以更好地控制其资源经济性。 它使用户能够:

  • 更好地利用他们已有的内存,
  • 自信地减少他们的记忆限制,知道 Go 会尊重他们,
  • 避免不支持的垃圾收集调整形式。

更新

此功能将在Go 1.19中发布

运行时现在包括对软内存限制的支持。 此内存限制包括 Go 堆和运行时管理的所有其他内存,不包括外部内存源,例如二进制文件本身的映射、以其他语言管理的内存以及操作系统代表 Go 程序持有的内存。

此限制可以通过runtime/debug.SetMemoryLimit或等效的GOMEMLIMIT环境变量进行管理。

该限制与runtime/debug.SetGCPercent / GOGC结合使用,即使GOGC=off也会受到尊重,从而允许 Go 程序始终最大限度地利用其内存限制,在某些情况下提高资源效率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM