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

Go 的 GC 是否将整个对象保存在内存中,同时保留指向某个字段的内部指针?


在这样的代码中,这会导致内存泄漏吗?或者 go 的 GC 是否“足够聪明”注意到不再需要对象的其余部分并将其从内存中清除?


package main


import (

    "fmt"

)


const aLot = 500000000


func 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)

}


繁星coding
浏览 135回答 2
2回答

www说

是的。内存将被保留,直到不再有任何对分配的任何部分的引用。通常的例子在切片技巧中给出切片技巧删除而不保留顺序a[i] = a[len(a)-1]  a = a[:len(a)-1]NOTE 如果元素的类型是指针或带指针字段的结构体,需要进行垃圾回收,上述Cut和Delete的实现存在潜在的内存泄漏问题:一些有值的元素仍然被切片a引用,从而无法收集。

LEATH

看profiler,好像确实是内存泄露(go1.11.5 darwin/amd64)让我们看看探查器。我在网上找到了调试内存的例子。通过适应我的示例,我这样做了:package mainimport (    "fmt"    "os"    "runtime"    "runtime/debug"    "runtime/pprof")const aLot = 5000000func 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 mainROUTINE ======================== 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:垃圾收集器似乎确实没有从内存中删除不需要的对象。如果我正确理解格式。(我可能不会,因为几乎没有文档。)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go