blog icon indicating copy to clipboard operation
blog copied to clipboard

Go 逃逸分析 | Go 语言高性能编程 | 极客兔兔

Open geektutu opened this issue 3 years ago • 10 comments

https://geektutu.com/post/hpg-escape-analysis.html

Go 语言/golang 高性能编程,Go 语言进阶教程,Go 语言高性能编程(high performance go)。介绍了 Go 内存分配逃逸分析(escape analysis)的几种典型场景,变量所使用的内存什么时候分配到栈上,什么时候分配到堆上。以及如何利用逃逸分析的原理优化代码的性能,例如传值 VS 传指针。

geektutu avatar Dec 30 '20 17:12 geektutu

Go 语言使用的是标记清除算法,并且在此基础上使用了三色标记法和写屏障技术,提高了效率。可以再开一篇详细介绍GC的专题问题吗?

lisgroup avatar Jun 03 '21 03:06 lisgroup

2.4 栈空间不足

不包含切片内部字段占用的内存大小。 创建了大小为 8192 的 int 型切片,恰好占用 64 KB 文章提到切片的实际内存占用还包括 Len、Cap 为什么 8192 个 int 就导致逃逸了呢?

lisgroup avatar Jun 03 '21 05:06 lisgroup

@lisgroup 这是表面测试的现象,很可能代码中只对底层数组的大小做了判断。这一块具体的实现还没看到。

geektutu avatar Jun 12 '21 06:06 geektutu

测试目标:返回指针与返回值性能对比 测试方式:基准测试,返回结构体 测试次数:10+ 测试结果:返回的数据量越大使用返回值形式,性能更好约10%-30%,各指数也比反回指针方式低那么一点 分析:返回值方式,内存分配到栈,而指针是分配到堆,频繁在堆上创建回收GC性能比内存拷贝性能低。估计可能是:在对象频繁创建和删除的场景下,传递指针导致的 GC 开销可能会严重影响性能。 但我把一个变量赋值给返回值的属性时,逃逸分析时看到这个变量是逃逸到了堆?返回值时存分配2次,而返回指针的方式内存分配3次?

nFreeMason avatar Sep 16 '21 06:09 nFreeMason

@geektutu @lisgroup 这是表面测试的现象,很可能代码中只对底层数组的大小做了判断。这一块具体的实现还没看到。

大佬,想继续请教一下,看结果这个 8192 字节只是 slice 底层数组的占用量,在runtime/slice.go 中 slice 定义有三个字段的,想问问 slice 在底层是怎么分配空间的

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

gosoon avatar Oct 14 '21 13:10 gosoon

“一般情况下,对于需要修改原对象值,或占用内存比较大的结构体,选择传指针。对于只读的占用内存较小的结构体,直接传值能够获得更好的性能。”

请教下,这占用内存较小的标准是? 占用多少内存算小呢?

zachturing avatar Oct 31 '21 02:10 zachturing

GO1.17 我执行代码 interface参数并没有出现逃逸现象

ngyhd avatar Mar 01 '22 06:03 ngyhd

还有一种情况,变量大小不确定时也会发生逃逸。

dablelv avatar Mar 10 '22 11:03 dablelv

文章写得挺好的,赞! 但是有一点,8192为啥是64KB,怎么算出来的

yangfx15 avatar Nov 11 '22 01:11 yangfx15

@yangfx15 文章写得挺好的,赞! 但是有一点,8192为啥是64KB,怎么算出来的

int 在 64 位机器是 int64,占 8 byte,8*8192/1024 = 64Kb

yanboer avatar Feb 22 '23 06:02 yanboer