ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Golang中逃逸现象-变量何时 栈何时堆

2021-02-12 22:05:44  阅读:216  来源: 互联网

标签:foo int 何时 Golang 逃逸 val3 new main


变量的逃逸现象

  • 将⼀个局部变量的地址返回给上层函数,依然能够访问,那么这个局部变量产⽣的了逃逸现象,当前变量应该并没有分配到栈上。
package main

//inline内联函数
func foo(arg_val int) *int {
	var foo_val1 int = 11
	var foo_val2 int = 12
	var foo_val3 int = 13
	var foo_val4 int = 14
	var foo_val5 int = 15

	//目的是防止编译器优化,优化成内联函数,而不产生foo函数的调用函数
	for i := 0; i < 5; i++ {
		//为了辨别每个变量的地址是否在栈上还是堆上
		println(&arg_val, &foo_val1, &foo_val2, &foo_val3, &foo_val4, &foo_val5)
	}

	//返回foo_val3的地址给main函数
	return foo_val3
}

func main() {

	main_val := foo(666)

	println(*main_val, main_val)
}

注意:以上函数在C++是编译不通过的,因为C++函数返回后,栈已经清空,这个时候,指针指向一个不存在的领域,则编译不通过

通过Golang编译器分析逃逸现象

在这里插入图片描述

  • go tool compile -m demo2.go

      通过提示得知哪些变量是被逃逸的
    
  • 编译汇编⽂件
    在这里插入图片描述
    发现foo_val3确实是通过runtime.newobject来开辟,是在堆上,不是栈上,确实发⽣逃逸

new出来的变量是在“栈”还是“堆”?

  • golang中的new,创建⼀个空间,未必是在堆上开辟的
    结论:Golang中⼀个函数局部变量,不管是不是动态new出来的,还是普通定义出来的,分配到堆上还是栈上,开发者决定不了。⽽是通过编译器做逃逸分析来决定的。

Golang中 new 和 make的区别?

  • 相同之处

      给变量分配空间的
    
  • 不同之处

      make 只是⽤slice、channel、map初始化,⽆可替代
      new ⽤于类型的内存分配(初始化是0),不常⽤, 原因 通过“:=”来初始化⽐较常⽤
    

标签:foo,int,何时,Golang,逃逸,val3,new,main
来源: https://blog.csdn.net/weixin_44879611/article/details/113131710

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有