我使用syscall pr限度来设置进程的资源限制,它可以限制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个字节,但它不会以任何方式发出信号段故障信号。
发布于 2014-07-02 09:44:38
RLIMIT_DATA
描述进程数据段的最大大小。传统上,分配内存的程序通过调用brk()
从操作系统分配内存来扩大数据段。
Go不使用这种方法。相反,它使用mmap()
系统调用的一个变体来请求地址空间中任何位置的内存区域。这比基于brk()
的方法灵活得多,因为您可以使用munmap()
来释放任意内存区域,而基于brk()
的方法只能从数据段的末尾释放内存。
其结果是,RLIMIT_DATA
在控制进程使用的内存量方面是不有效的。尝试使用RLIMIT_AS
,但是请注意,这个限制也包含了用于文件映射的地址空间,特别是在共享库的情况下。
发布于 2022-01-24 08:44:43
有一个建议是软记忆极限,它可能会在go 1.18之后发布
该选项有两种形式:一个名为
runtime/debug
的新SetMemoryLimit
函数和一个GOMEMLIMIT
环境变量。总之,运行时将试图通过限制堆的大小和更积极地将内存返回到底层平台来维护这个内存限制。这包括一种帮助减少垃圾收集死亡螺旋的机制。最后,通过设置GOGC=off,Go运行时将始终将堆增长到完全内存限制。这个新选项使应用程序能够更好地控制其资源经济性。它授权用户:
更新
这个特性将在去1.19中发布。
运行时现在包括对软内存限制的支持。此内存限制包括Go堆和运行时管理的所有其他内存,并排除外部内存源,例如二进制本身的映射、以其他语言管理的内存以及操作系统代表Go程序持有的内存。
这个限制可以通过runtime/debug.SetMemoryLimit
或等效的GOMEMLIMIT
环境变量来管理。
该限制与runtime/debug.SetGCPercent
/ GOGC
一起工作,即使是GOGC=off
也会受到尊重,允许Go程序始终最大限度地利用其内存限制,从而在某些情况下提高资源效率。
以下是关于每个memory limit
使用Go垃圾收集器指南的一些建议
虽然内存限制是一个强大的工具,Go运行时会采取步骤来减少误用造成的最坏行为,但是谨慎地使用它仍然是很重要的。下面是关于内存限制在哪里最有用和最适用,以及它可能造成的危害大于好处的建议的集合。
https://stackoverflow.com/questions/24522692
复制相似问题