加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 01:48:16 所属栏目:安全 来源:网络整理
导读:我使用syscall prlimit设置资源限制来处理,它适用于限制CPU时间,但是当测试内存使用时,我遇到了问题. package sandboximport ( "syscall" "unsafe")func prLimit(pid int,limit uintptr,rlimit *syscall.Rlimit) error { _,_,errno := syscall.RawSyscall6(s
我使用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)
    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,但要注意此限制还包含用于文件映射的地址空间,尤其是在共享库的情况下.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读