猿问

如何在golang中手动释放内存

下面是计算 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?


梵蒂冈之花
浏览 331回答 2
2回答

温温酱

根据此提案:arena:提供内存 arenas 的新包arena我们建议在 Go 标准库中添加一个新包。arena 包将允许分配任意数量的竞技场。可以从竞技场的内存中分配任意类型的对象,并且竞技场的大小会根据需要自动增长。当 arena 中的所有对象都不再使用时,可以显式释放 arena 以有效地回收其内存,而无需进行一般的垃圾收集。我们要求实施提供安全检查,这样,如果无竞技场的操作不安全,程序将在任何不正确的行为发生之前终止。该功能已经合并到arena下的 master 分支,可能会在 go 1.20 中发布。使用该arena包,您可以自己分配内存,如果不再使用则手动释放它。示例代码&nbsp;a := arena.NewArena()&nbsp; &nbsp; defer a.Free()&nbsp; &nbsp; tt := arena.New[T1](a)&nbsp; &nbsp; tt.n = 1&nbsp; &nbsp; ts := arena.MakeSlice[T1](a, 99, 100)&nbsp; &nbsp; if len(ts) != 99 {&nbsp; &nbsp; &nbsp; &nbsp; t.Errorf("Slice() len = %d, want 99", len(ts))&nbsp; &nbsp; }&nbsp; &nbsp; if cap(ts) != 100 {&nbsp; &nbsp; &nbsp; &nbsp; t.Errorf("Slice() cap = %d, want 100", cap(ts))&nbsp; &nbsp; }&nbsp; &nbsp; ts[1].n = 42

慕雪6442864

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

相关分类

Go
我要回答