为了账号安全,请及时绑定邮箱和手机立即绑定

如何在golang中手动释放内存

如何在golang中手动释放内存

Go
梵蒂冈之花 2022-12-19 17:55:16
下面是计算 C(36,8) 并将结果保存到文件的代码func combine_dfs(n int, k int) (ans [][]int) {    temp := []int{}    var dfs func(int)    dfs = func(cur int) {        if len(temp)+(n-cur+1) < k {            return        }        if len(temp) == k {            comb := make([]int, k)            copy(comb, temp)            ans = append(ans, comb)            return        }        temp = append(temp, cur)        dfs(cur + 1)        temp = temp[:len(temp)-1]        dfs(cur + 1)    }    dfs(1)    return}func DoCombin() {    fmt.Printf("%v\n", "calculator...")    cst := []byte{}    for i := 'a'; i <= 'z'; i++ {        cst = append(cst, byte(i))    }    for i := '0'; i <= '9'; i++ {        cst = append(cst, byte(i))    }    n := 36    k := 8    arr := combine_dfs(n, k)    fmt.Printf("%v\n", "writefile...")    file, _ := os.OpenFile("result.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR|os.O_APPEND, 0666)    defer file.Close()    for _, m := range arr {        b:= bytes.Buffer{}        b.Reset()        for _, i := range m {            b.WriteByte(cst[i-1])        }        b.WriteByte('\n')        file.Write(b.Bytes())    }}但是我写文件太慢了..所以我想使用 goroutine 来写文件(使用 pool 来限制 goroutine 的数量):func DoCombin2() {    fmt.Printf("%v\n", "calculator...")    cst := []byte{}    for i := 'a'; i <= 'z'; i++ {        cst = append(cst, byte(i))    }    for i := '0'; i <= '9'; i++ {        cst = append(cst, byte(i))    }    n := 36    k := 8    arr := combine_dfs(n, k)    fmt.Printf("%v\n", "writefile...")    file, _ := os.OpenFile("result.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR|os.O_APPEND, 0666)    defer file.Close()    pool := make(chan int, 100)    for _, m := range arr {        go func(m []int) {            pool <- 1            b := bytes.Buffer{}            b.Reset()            for _, i := range m {                b.WriteByte(cst[i-1])            }        }(m)    }}有什么办法可以避免内存爆炸?1.为什么使用了sync.Pool后还是无法避免?2.有什么方法可以限制 Windows 中的内存使用(我知道在 Linux 中)?3.还有其他方法可以避免内存爆炸吗?4.内存爆炸是因为bytes.Buffer吗?如何手动释放 bytes.Buffer?
查看完整描述

2 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

根据此提案:arena:提供内存 arenas 的新包

arena我们建议在 Go 标准库中添加一个新包。arena 包将允许分配任意数量的竞技场。可以从竞技场的内存中分配任意类型的对象,并且竞技场的大小会根据需要自动增长。当 arena 中的所有对象都不再使用时,可以显式释放 arena 以有效地回收其内存,而无需进行一般的垃圾收集。我们要求实施提供安全检查,这样,如果无竞技场的操作不安全,程序将在任何不正确的行为发生之前终止。

该功能已经合并到arena下的 master 分支,可能会在 go 1.20 中发布。使用该arena包,您可以自己分配内存,如果不再使用则手动释放它。

示例代码

 a := arena.NewArena()

    defer a.Free()


    tt := arena.New[T1](a)

    tt.n = 1


    ts := arena.MakeSlice[T1](a, 99, 100)

    if len(ts) != 99 {

        t.Errorf("Slice() len = %d, want 99", len(ts))

    }

    if cap(ts) != 100 {

        t.Errorf("Slice() cap = %d, want 100", cap(ts))

    }

    ts[1].n = 42


查看完整回答
反对 回复 2022-12-19
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

在 1.19 中

垃圾收集器增加了对软内存限制的支持,

垃圾收集器添加了对软内存限制的支持,在新的垃圾收集指南中有详细讨论。该限制对于优化 Go 程序以在具有专用内存量的容器中尽可能高效地运行特别有用。

新的垃圾收集指南


查看完整回答
反对 回复 2022-12-19
  • 2 回答
  • 0 关注
  • 330 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号