Thank you Ian for the great answer.
在2021年11月4日星期四 UTC+8 上午7:21:57<Ian Lance Taylor> 写道:

> On Wed, Nov 3, 2021 at 8:56 AM Ge <everg...@gmail.com> wrote:
> >
> > Hi, recently I was trying to figure out how GC marks stack objects and 
> found
> > some places of the implementation detail over my head.
> >
> > source:
> > ```
> > package main
> >
> > import "runtime"
> >
> > func main() {
> > x := make([]byte, 256*1024*1024)
> > runtime.GC() ← t1
> > x[0] = 2
> >
> > runtime.GC() ← t2
> > println("x released")
> > runtime.GC()
> > println("over")
> > }
> > ```
> >
> > The GC trace info was like this:
> > ```
> > ➜ gc GODEBUG=gctrace=1 ./largeslice
> > gc 1 @0.009s 0%: 0.051+0.27+0.005 ms clock, 0.40+0/0.18/0.034+0.040 ms 
> cpu, 256->256->256 MB, 257 MB goal, 8 P (forced)
> > gc 2 @0.010s 1%: 0.033+0.21+0.004 ms clock, 0.26+0/0.16/0.078+0.032 ms 
> cpu, 256->256->256 MB, 512 MB goal, 8 P (forced)
> > gc 3 @0.012s 1%: 0.019+0.091+0.003 ms clock, 0.15+0/0.15/0.047+0.024 ms 
> cpu, 256->256->0 MB, 512 MB goal, 8 P (forced)
> > x released
> > gc 4 @0.013s 1%: 0.014+0.11+0.004 ms clock, 0.11+0/0.13/0.058+0.036 ms 
> cpu, 0->0->0 MB, 4 MB goal, 8 P (forced)
> > over
> > ```
> > It seems that the slice x could be garbage collected after the last use 
> of it,
> > which feels so intelligent and a little confusing, since fucntion call 
> did't return yet,
> > and made me wondering how Golang dynamically identify these stack 
> objects.
> >
> > ```
> > // https://github.com/golang/go/blob/master/src/runtime/stack.go#L1246
> > func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) 
> (locals, args bitvector, objs []stackObjectRecord) {
> > ...
> > stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
> > ...
> > ```
> >
> > AFAIK stack pointer maps are got via getStackmap function, which
> > reads FUNCDATA info from gopclntab(not very sure about this) section.
> >
> > My question is that will GC get different stack maps at t1 and t2 ?
> > And if so how Golang implemented it, as GC stack scanning could happen
> > at any time, which means for different pc there maybe lot of possiblites
> > of stack maps.
>
> Yes, the GC will see a different map of live pointers on the stack at t1 
> and t2.
>
> A GC can occur at any point where a goroutine can be preempted. That
> means that the live pointer map has to be conservatively correct at
> all such points. I say conservatively correct because while it is
> essential that any live pointer be in the stack map, it is OK if a
> previously live pointer remains in the stack map even after it is no
> longer live. That will mean that the value stays live longer than
> necessary, but it otherwise doesn't matter. In practice the compiler
> builds stack maps that are correct at each function call. You can see
> the livemaps generated by the compiler if you build with
> -gcflags=-live=1.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4790afc1-6dc2-4dee-abb9-61d2c67849b9n%40googlegroups.com.

Reply via email to