You're correct. I'm sorry about my first response; it was too brief and led to the confusion you have. The Go escape analysis algorithm has a concept of "loopdepth" (shortened as ld in debug output). The loopdepth is -1 for global variables, 0 for input arguments to a function, 1 for the top level of a function, and is incremented by 1 for each for or label statement encountered to mark a new independent scope. In your most recent example, using `{ }` creates a new scope technically, but for our purposes in escape analysis, we only consider loops and labels as new scope; that means if statements and switch statements are not counted as well. Every expression and statement is given a loopdepth and when walking through the graph of connected nodes, we consider an expression to be leaking if it involves a dereference and the lhs has a lower loopdepth than the rhs ( https://github.com/golang/go/blob/master/src/cmd/compile/internal/gc/esc.go#L1803 ).
For the most recent example, this is the output I get from -gcflags "-m -m -m -m": # command-line-arguments ./ex.go:3: can inline @"".main as: func() { var @"".m·1 map[int]int; ; @"".m·1 = make(map[int]int); _ = @"".m·1 } ./ex.go:4:[1] main esc: m ./ex.go:4:[1] main esc: var m map[int]int ./ex.go:4:[1] main esc: m ./ex.go:4:[1] main esc: m = <N> ./ex.go:7:[1] main esc: m ./ex.go:7:[1] main esc: 0 ./ex.go:7:[1] main esc: make(map[int]int) ./ex.go:7:[1] main esc: m = make(map[int]int) ./ex.go:7:[1] main escassign: m( l(4) class(PAUTO) f(1) ld(1) assigned)[NAME] = make(map[int]int)( l(7) esc(no) ld(1))[MAKEMAP] ./ex.go:7::flows:: m <- make(map[int]int) ./ex.go:10:[1] main esc: _ ./ex.go:10:[1] main esc: m ./ex.go:10:[1] main esc: _ = m escflood:0: dst m scope:main[1] escwalk: level:{0 0} depth:0 op=MAKEMAP make(map[int]int)( l(7) esc(no) ld(1)) scope:main[1] extraloopdepth=-1 ./ex.go:7: main make(map[int]int) does not escape Let's focus on the following line: ./ex.go:7:[1] main escassign: m( l(4) class(PAUTO) f(1) ld(1) assigned)[NAME] = make(map[int]int)( l(7) esc(no) ld(1))[MAKEMAP] This describes line 7: `m = make(map[int]int)`. Notice that both `m` and `make(map[int]int)` has loopdepth, ld(1). This is not considered to be a leak. Now let's look at your first escaping example, which you labeled as example2.go: # command-line-arguments ./example2.go:5:[1] main esc: m ./example2.go:5:[1] main esc: var m map[int]int ./example2.go:5:[1] main esc: m ./example2.go:5:[1] main esc: m = <N> ./example2.go:6:[2] main esc: false ./example2.go:7:[2] main esc: m ./example2.go:7:[2] main esc: 0 ./example2.go:7:[2] main esc: make(map[int]int) ./example2.go:7:[2] main esc: m = make(map[int]int) ./example2.go:7:[2] main escassign: m( l(5) class(PAUTO) f(1) ld(1) assigned)[NAME] = make(map[int]int)( l(7) esc(no) ld(2))[MAKEMAP] ./example2.go:7::flows:: m <- make(map[int]int) ./example2.go:6:[1] main esc: for loop ./example2.go:10:[1] main esc: _ ./example2.go:10:[1] main esc: m ./example2.go:10:[1] main esc: _ = m escflood:0: dst m scope:main[1] escwalk: level:{0 0} depth:0 op=MAKEMAP make(map[int]int)( l(7) esc(no) ld(2)) scope:main[2] extraloopdepth=-1 ./example2.go:7: make(map[int]int) escapes to heap ./example2.go:7: from m (assigned) at ./example2.go:5 And focus on the corresponding line: ./example2.go:7:[2] main escassign: m( l(5) class(PAUTO) f(1) ld(1) assigned)[NAME] = make(map[int]int)( l(7) esc(no) ld(2))[MAKEMAP] Note that the loopdepth, ld, of `m` is 1, and the loopdepth, ld of `make(map[int]int)` is 2. When walking through the MAKEMAP op `escwalk: level:{0 0} depth:0 op=MAKEMAP make(map[int]int)( l(7) esc(no) ld(2)) scope:main[2] extraloopdepth=-1`, we consider `make(map[int]int)` to be leaking and decide to heap allocate it. I hope that explanation clarifies the decision made by the compiler in these different example. Feel free to ask more questions if you'd like. You can message me directly if you don't want to clutter the mailing list. Thanks, Chris On Thu, Sep 29, 2016 at 8:20 PM, 刘桂祥 <liuguixiang...@gmail.com> wrote: > package main > > func main() { > var m map[int]int > > { > m = make(map[int]int) > } > > _ = m > } > > if I do this m will not escape just want to know what's the scope rule for > escape ? puzzled > <http://www.baidu.com/link?url=ApC817U9uUoCFHhS_dqb5JzUWJQsslUUA6_TDv3LDZBJgaA-G2ZbRfWA-2cGajgU_MHmTiXVEouMmdPN53mMMXxYd1nvCWWJJvfu5Mmg4Ca> > > > 在 2016年9月29日星期四 UTC+8上午1:39:09,Chris Manghane写道: >> >> In the first example, make does not escape the scope of the for >> statement. In the second example, make is assigned to m, which is outside >> of the scope of the for statement, which means the make operation escapes >> its scope and subsequently, is heap allocated. If you want more information >> about why something escapes, try compiling with -gcflags "-m -m" for an >> explanation of the escape analysis information. >> >> On Wed, Sep 28, 2016 at 7:56 AM, 刘桂祥 <liuguix...@gmail.com> wrote: >> >>> go 1.7 >>> >>> 在 2016年9月28日星期三 UTC+8下午10:41:09,Dave Cheney写道: >>> >>>> Which version of Go? >>>> >>>> On Thursday, 29 September 2016 00:18:29 UTC+10, 刘桂祥 wrote: >>>>> >>>>> // example1.go >>>>> package main >>>>> >>>>> >>>>> func main() { >>>>> >>>>> for i := 0; i < 2; i++ { >>>>> m := make(map[int]int) >>>>> >>>>> >>>>> m[1] = 100 >>>>> } >>>>> >>>>> >>>>> } >>>>> >>>>> >>>>> main make(map[int]int) does not escape >>>>> >>>>> >>>>> // example2.go >>>>> package main >>>>> >>>>> >>>>> func main() { >>>>> var m map[int]int >>>>> for i := 0; i < 2; i++ { >>>>> m = make(map[int]int) >>>>> >>>>> >>>>> m[1] = 100 >>>>> } >>>>> >>>>> >>>>> } >>>>> >>>>> make(map[int]int) escapes to heap why ??? >>>>> >>>>> >>>>> -- >>> 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...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- > 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. > For more options, visit https://groups.google.com/d/optout. > -- 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. For more options, visit https://groups.google.com/d/optout.