Categories: GO编程

golang内存逃逸

栈是线程级别的,大小在创建的时候已经确定,当变量太大的时候,会"逃逸"到堆上,这种现象称为内存逃逸。

内存逃逸的场景

指针逃逸

Go可以返回局部变量指针,这种情况下,函数虽然退出了,但是因为指针的存在,对象的内存不能随着函数结束而回收,因此只能分配在堆上。

package main

type User struct {
    Name string
}

func foo(s string) *User {
    u := new(User)
    u.Name = s
    return u // 1.方法内局部变量返回,逃逸
}

func main() {
    user := foo("gui")
    user.Name = "dev"
}
/* 逃逸分析日志
# command-line-arguments
./main.go:11:6: can inline foo
./main.go:17:6: can inline main
./main.go:18:13: inlining call to foo
./main.go:11:10: leaking param: s
./main.go:12:10: new(User) escapes to heap  # 逃逸
./main.go:18:13: new(User) does not escape
*/

栈空间不足逃逸

当栈空间不足以存放当前对象时或无法判断当前切片长度时会将对象分配到堆中。

interface{} 动态类型逃逸

在 Go 中,空接口 interface{} 可以表示任意的类型,如果函数参数为 interface{},编译期间很难确定其参数的具体类型,也会发生逃逸。

package main

import "fmt"

func main() {
    name := "devhui"
    fmt.Println(name)
}
/* 逃逸分析日志
# command-line-arguments
./main.go:7:13: inlining call to fmt.Println
./main.go:7:13: name escapes to heap # 逃逸
./main.go:7:13: []interface {} literal does not escape
*/

闭包引用对象逃逸

package main

func main() {
 f := fibonacci()
 for i := 0; i < 10; i++ {
  f()
 }
}
func fibonacci() func() int {
 a, b := 0, 1
 return func() int {
  a, b = b, a+b
  return a
 }
}
/*
$ go build -gcflags=-m
# ceshi
.\main.go:11:9: can inline fibonacci.func1
.\main.go:10:2: moved to heap: a
.\main.go:10:5: moved to heap: b
.\main.go:11:9: func literal escapes to heap
*/

逃逸分析基本原则

编译器会根据变量是否被外部引用来决定是否逃逸:

如果函数外部没有引用,则优先放到栈中;
如果函数外部存在引用,则必定放到堆中;
如果栈上放不开,则必定放到堆上;

逃逸分析参数

go build -gcflags="-l -m" -o main   main.go
# 删除文件
 rm main

内存逃逸分析的好处

  • 栈上分配内存比在堆中分配内存效率更高
  • 栈上分配的内存不需要 GC 处理,而堆需要
  • 逃逸分析目的是决定内分配地址是栈还是堆
  • 逃逸分析在编译阶段完成
5.0
02
golang逗号模式
BOM 头是什么,怎么除去
嘻嘻

嘻嘻IT: 笔者是一个工作七八年的程序猿老鸟,从事涉及的技术栈主要包括PHP、Linux、Devops等,喜欢研究新技术,尝试新技术,提升技术自动化和开发效率,致力于write less,do more! 技术每年都会层出不穷,领域划分的越来越细,不可能学习所有的东西,保持对技术的好奇心,理解技术中核心思想,做一个有深度,有思想的开发!

Recent Posts

CrowdStrike是一个AI云原生平台

CrowdStrike是全球网…

14小时 ago

Tabnine是一款AI编程助手

Tabnine是一款最新的AI…

2天 ago

Adrenaline一个AI开发工具

Adrenaline是一个革命…

2天 ago

Kubeflow一个简化Kubernetes学习工作流程工具

在机器学习(ML)领域,有效地…

2天 ago

CodiumAI一个AI测试工具

CodiumAI不完全依赖于手…

2天 ago

Writesonic一个AI创作助手

Writesonic是一个先进…

2天 ago