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

go GC 是否将整个对象保存在内存中,同时保留指向一个字段的内部指针?这会导致内存泄漏吗?

go GC 是否将整个对象保存在内存中,同时保留指向一个字段的内部指针?这会导致内存泄漏吗?

Go
繁星coding 2023-06-12 16:27:40
Go 的 GC 是否将整个对象保存在内存中,同时保留指向某个字段的内部指针?在这样的代码中,这会导致内存泄漏吗?或者 go 的 GC 是否“足够聪明”注意到不再需要对象的其余部分并将其从内存中清除?package mainimport (    "fmt")const aLot = 500000000func getInteriorPointer() *int {    type bigStruct struct {        someBigThing [aLot]int        smallThing   int    }    b := bigStruct{smallThing: 3}    return &b.smallThing}func main() {    p := getInteriorPointer()    // keep using p in the rest of the app,     // never using someBigThing from the struct    fmt.Println(*p)}
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

是的。内存将被保留,直到不再有任何对分配的任何部分的引用。

通常的例子在切片技巧中给出

切片技巧

删除而不保留顺序

a[i] = a[len(a)-1] 
a = a[:len(a)-1]

NOTE 如果元素的类型是指针或带指针字段的结构体,需要进行垃圾回收,上述Cut和Delete的实现存在潜在的内存泄漏问题:一些有值的元素仍然被切片a引用,从而无法收集。


查看完整回答
反对 回复 2023-06-12
?
LEATH

TA贡献1936条经验 获得超6个赞

看profiler,好像确实是内存泄露(go1.11.5 darwin/amd64)


让我们看看探查器。

我在网上找到了调试内存的例子。通过适应我的示例,我这样做了:

package main


import (

    "fmt"

    "os"

    "runtime"

    "runtime/debug"

    "runtime/pprof"

)


const aLot = 5000000


func getInteriorPointer() *int {

    type bigStruct struct {

        someBigThing [aLot]int

        smallThing   int

    }

    b := bigStruct{smallThing: 3}

    return &b.smallThing

}


func main() {

    p := getInteriorPointer()

    runtime.GC()

    debug.FreeOSMemory()

    fmem, _ := os.Create("prof.prof")

    pprof.WriteHeapProfile(fmem)


    // keep using p in the rest of the app,

    // never using someBigThing from the struct

    fmt.Println(*p)

}

现在我go tool pprof prof.prof跑list main


ROUTINE ======================== main.getInteriorPointer in /Users/karel/exp/exp.go

   38.15MB    38.15MB (flat, cum)   100% of Total

         .          .     13:func getInteriorPointer() *int {

         .          .     14:   type bigStruct struct {

         .          .     15:           someBigThing [aLot]int

         .          .     16:           smallThing   int

         .          .     17:   }

   38.15MB    38.15MB     18:   b := bigStruct{smallThing: 3}

         .          .     19:   return &b.smallThing

         .          .     20:}

         .          .     21:

         .          .     22:func main() {

         .          .     23:   p := getInteriorPointer()

ROUTINE ======================== main.main in /Users/karel/exp/exp.go

         0    38.15MB (flat, cum)   100% of Total

         .          .     18:   b := bigStruct{smallThing: 3}

         .          .     19:   return &b.smallThing

         .          .     20:}

         .          .     21:

         .          .     22:func main() {

         .    38.15MB     23:   p := getInteriorPointer()

         .          .     24:   runtime.GC()

         .          .     25:   debug.FreeOSMemory()

         .          .     26:   fmem, _ := os.Create("prof.prof")

         .          .     27:   pprof.WriteHeapProfile(fmem)

         .          .     28:

垃圾收集器似乎确实没有从内存中删除不需要的对象。如果我正确理解格式。(我可能不会,因为几乎没有文档。)


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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信