doubts about the output of escape analysis

184 views
Skip to first unread message

Leonard Wang

unread,
May 16, 2020, 3:11:00 PM5/16/20
to golang-dev
Do the meaning of these three types of outputs have detailed explanation?  
Or is there a document or design document about escape analysis?   
Thank you!

```
escapes to heap
leaking param
moved to heap
```

According to my test result,  
`moved to heap` is allocated on the heap,  
The other two are not always on the heap.  

>You can think of escapes to heap as a debug message, it does not indicate that one of your variables is "relocated" to the heap.  

So the other two are debug messages?
Only `moved to heap`  is the definite result?

my examples:
```
package main

import (
"fmt"
"unsafe"
)

//go:linkname inheap runtime.inheap
func inheap(b uintptr) bool

func f0_0() {
var x int
f0_1(&x)
}

func f0_1(a *int) { // a does not escape
println("f0_1:a", inheap(uintptr(unsafe.Pointer(&a)))) // f0_1:a false
}

func f1_0() {
var x int
f1_1(&x)
}

func f1_1(a *int) {
fmt.Println(a)                                         // leaking param: a
println("f1_1:a", inheap(uintptr(unsafe.Pointer(&a)))) // f1_1:a false
}

var global1 *int
var global2 **int

func f2_0() {
var x int
f2_1(&x)
}

func f2_1(a *int) {
global1 = a                                            // leaking param: a
println("f2_1:a", inheap(uintptr(unsafe.Pointer(&a)))) // f2_1:a false
}

func f3_0() {
var x int
f3_1(&x)
}

func f3_1(a *int) {
global2 = &a                                           // moved to heap: a
println("f3_1:a", inheap(uintptr(unsafe.Pointer(&a)))) // f3_1:a true
}

func f4_0() {
var x int
f4_1(x)
}

func f4_1(a int) {
fmt.Println(a)                                         // a escapes to heap
println("f4_1:a", inheap(uintptr(unsafe.Pointer(&a)))) // f4_1:a false
}

func main() {
f0_0()
f1_0()
f2_0()
f3_0()
f4_0()
}

```
You can add `empty.s` and run 
```
go build -gcflags='-m'
./XXX
```
to get the result.

Ian Lance Taylor

unread,
May 16, 2020, 3:28:48 PM5/16/20
to Leonard Wang, golang-dev
On Sat, May 16, 2020 at 12:11 PM Leonard Wang <wangde...@gmail.com> wrote:
>
> Do the meaning of these three types of outputs have detailed explanation?
> Or is there a document or design document about escape analysis?
> Thank you!
>
> ```
> escapes to heap
> leaking param
> moved to heap
> ```
>
> According to my test result,
> `moved to heap` is allocated on the heap,
> The other two are not always on the heap.
>
> I found [an answer](https://stackoverflow.com/questions/51518742/what-is-the-meaning-of-the-output-from-go-run-gcflags-m-xxx-go)
> >You can think of escapes to heap as a debug message, it does not indicate that one of your variables is "relocated" to the heap.
>
> So the other two are debug messages?
> Only `moved to heap` is the definite result?

All of these messages are debugging messages. They are intended to
help people interested in a detailed understanding of the memory
behavior of their program.

"moved to heap" means that a local variable was allocated on the heap
rather than the stack.

"leaking param" means that the memory associated with some parameter
(e.g., if the parameter is a pointer, the memory to which it points)
will escape. This typically means that the caller must allocate that
memory on the heap.

"escapes to heap" means that some value was copied into the heap.
This differs from "moved to heap" in that with "moved to heap" the
variable was allocated in the heap. With "escapes to heap" the value
of some variable was copied, for example when assigning to a variable
of interface type, and that copy forced the value to be copied into a
newly allocated heap slot.

Hope this helps.

Ian

Matthew Dempsky

unread,
May 16, 2020, 4:54:33 PM5/16/20
to Leonard Wang, golang-dev
On Sat, May 16, 2020 at 12:11 PM Leonard Wang <wangde...@gmail.com> wrote:
So the other two are debug messages?
Only `moved to heap`  is the definite result?

No, "moved to heap" and "escapes to heap" both always mean a heap allocation occurs. The difference is "moved to heap" is used for named variables, and "escapes to heap" is used for anonymous variables (e.g., as allocated by "new" or "make"; taking the address of a composite literal).

func f4_1(a int) {
fmt.Println(a)                                         // a escapes to heap

Here "escapes to heap" is referring to that a is being copied to the heap so it can be passed as an interface{}.

It might be clearer if the diagnostic was "interface{}(a) escapes to heap"; but for consistency/simplicity, we omit implicit conversions when printing diagnostics.

Leonard Wang

unread,
May 16, 2020, 10:22:25 PM5/16/20
to golang-dev
Got it.  
This solved my doubts, thank you very much!

在 2020年5月17日星期日 UTC+8上午4:54:33,Matthew Dempsky写道:

Leonard Wang

unread,
May 16, 2020, 10:38:16 PM5/16/20
to golang-dev
Got it.    
This solved my doubts, thank you very much!  

在 2020年5月17日星期日 UTC+8上午3:28:48,Ian Lance Taylor写道:
Reply all
Reply to author
Forward
0 new messages