返回顶部
首页 > 资讯 > 后端开发 > GO >GO中什么情况会使用变量逃逸
  • 268
分享到

GO中什么情况会使用变量逃逸

GO变量逃逸 2023-02-14 12:02:42 268人浏览 薄情痞子
摘要

目录C 程序Go 程序GO 的逃逸是啥样子的?你知道 GO 中什么情况会变量逃逸吗?首先我们先来看看什么是变量逃逸 Go 语言将这个以前我们写 C/C++ 时候需要做的内存规划和分配

你知道 GO 中什么情况会变量逃逸吗?首先我们先来看看什么是变量逃逸

Go 语言将这个以前我们写 C/C++ 时候需要做的内存规划和分配,全部整合到了 GO 的编译器中,GO 中将这个称为 变量逃逸

GO 通过编译器分析代码的特征和代码的生命周期,决定应该使用堆还是栈来进行内存分配

C 代码 和 GO 代码对比哪个会崩溃?

咱们写一个简单的例子,在 C 里面内存分配到栈上面还是堆上面是一个很明确的事情

例如

函数中的变量是分配在栈上面,会随着该函数调用完毕后随之销毁掉

程序员自己 malloc 开辟的内存是在堆上面,需要程序员自己去释放

那么问题来了:

如果我们将某一个函数中的局部变量的地址(全篇以局部变量为例),作为该函数的返回值,最终在函数外部去访问这个局部变量的地址,是否会出错呢?一起来看看吧

C 程序

test.c

int * get_res(int num){
    int tmp = num + 10;
    return &tmp;
}

int main(){
    int * res = get_res(80);
    printf("%d  -- %p\n" , *res, res);
}

上面写了一个简单的 C 代码,获取传入数据并 + 10 得到的结果

# GCc test.c  -o test
test.c: In function ‘get_res':
test.c:7:12: warning: function returns address of local variable [-Wreturn-local-addr]
     return &tmp;
            ^~~~
# ./test
Segmentation fault

这里可以看出编译程序,报了 warning 了,不过不影响程序的编译 , 这个 warning 报错信息是 因为我们返回了临时变量的地址,C 编译器检测到了,给我们抛出了一个 warning

执行编译的程序后,崩溃了 , 熟悉 C 的小伙伴一点都不惊慌,他们不会写出这种代码

出现 段错误 的原因很明显,上面有说到,是因为外部访问了局部变量的地址,外部访问的时候,此时这个局部变量已经被销毁了,此时外部访问的这个指针,属于野指针,因此出现程序崩溃

GO 程序

go 程序的逻辑和上面 C 程序的逻辑一模一样,那么我们看看是否会出现程序崩溃呢

func getRes(num int) *int {
	tmp := num + 10
	return &tmp
}
func main() {
	res := getRes(80)
	fmt.Printf("%d  -- %p\n", *res, res)
}

执行上述代码,查看效果

# go run main.go
90  -- 0xc420018078

熟悉 go 语言的 小伙伴看到这里心中也毫无波澜,程序正常执行,没有崩溃,因为他们知道原因,这个现象属于 变量逃逸

那么我们一起来看看 GO 为什么会这样做,是如何做的呢?

GO 的逃逸是啥样子的?

上面有说到 GO 不会像 C/c++ 一样需要程序员自己去关心内存分配,是期望 GO 程序员更多的关注逻辑

因此内存分配这一块,GO 编译器都做的妥妥的,一个变量是分配在栈上面还是堆上面,不是简单的看一个变量是局部变量就分配到栈上,这个是根据具体的使用的,有时候它也会被分配到堆上面

当我们发现本应该分配在栈上面的变量,却分配在堆上面了,说明发生了逃逸

开始探究和验证

我们可以尝试写一个简单的 demo ,还是将局部变量的地址返回到外部去,外部来访问这个局部变量的地址

func getRes(tmp int) *int {

	var t1 int = 1
	var t2 int = 2
	var t3 int = 3

	println(&tmp, &t1, &t2, &t3)

	return &t2
}

func main() {
	res := getRes(80)
	println(*res, res)
}

执行上述代码查看效果

# go run main.go
0xc420045f50 0xc420045f68 0xc420045f60 0xc420045f58
2 0xc420045f60

通过上面的将变量地址打印出来貌似没有看出上面端倪,地址是也是连续的

那么我们使用 go 提供的工具来看看这个程序是不是存在逃逸

执行 # go tool compile -m main.go 查看效果如下

main.go:11:9: &t2 escapes to heap
main.go:6:6: moved to heap: t2

go tool compile 工具很明显的调试出来说明 t2 这个变量已经逃逸到 堆上面去了

感兴趣的话还可以利用工具瞅一眼汇编,多了解一点也有好处

刚才参数 -m 是直接查看是否逃逸,我们可以加 -S 会打印出具体的会变代码,查看该变量是否是 new 出来的

# go tool compile -S main.go | grep new
0x0035 00053 (main.go:6)        CALL    runtime.newobject(SB)
rel 54+4 t=8 runtime.newobject+0

对应的看看代码,就是 创建 t2 变量的这一行

对于 go tool compile 工具,我们可以通过 help 命令来查看一下

# go tool compile --help

到此这篇关于GO中什么情况会使用变量逃逸的文章就介绍到这了,更多相关GO 变量逃逸内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: GO中什么情况会使用变量逃逸

本文链接: https://lsjlt.com/news/195990.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • GO中什么情况会使用变量逃逸
    目录C 程序GO 程序GO 的逃逸是啥样子的?你知道 GO 中什么情况会变量逃逸吗?首先我们先来看看什么是变量逃逸 Go 语言将这个以前我们写 C/C++ 时候需要做的内存规划和分配...
    99+
    2023-02-14
    GO 变量逃逸
  • Go语言中的逃逸分析究竟是什么?
    目录1、逃逸分析介绍2、Go中内存分配在哪里?3、Go与C++内存分配的区别4、逃逸分析骚操作5、逃逸分析引申示例说明 1、逃逸分析介绍 学计算机的同学都知道,在编译原理中,分析指针...
    99+
    2024-04-02
  • Go语言中内存管理逃逸的方法是什么
    本篇内容介绍了“Go语言中内存管理逃逸的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 前言所谓的逃逸分析(Escape an...
    99+
    2023-07-05
  • Angular中什么是变更检测?什么情况下会引起变更检测?
    Angular中什么是变更检测?下面本篇文章带大家了解一下变更检测,并介绍一下什么情况下会引起变更检测,希望对大家有所帮助!什么是变更检测?简单来说,变更检测就是Angular用来检测视图与模型之间绑定的值是否发生了改变,当检测到模型中的值...
    99+
    2023-05-14
    Angular 变更检测
  • 在什么情况下会使用mysql临时表
    这篇文章主要介绍在什么情况下会使用mysql临时表,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!MySQL在很多情况下都会用到临时表,总结一下什么时候会用到临时表:什么是临时表:My...
    99+
    2024-04-02
  • Go语言应该什么情况使用指针
    目录什么是指针 指针的声明和定义 var 关键字声明 new 函数声明 指针的操作 指针参数 指针接收者什么情况下使用指针什么是指针 我们都知道,程序运行时的数据是存放在内存中的,...
    99+
    2024-04-02
  • 如果我使用返回多行的语句为 MySQL 用户变量赋值,会发​​生什么情况?
    万一,如果我们使用返回多行的语句为用户变量赋值,那么最后一行的值将保存在该用户变量中,因为用户变量可以保存只有单一值。在下面的示例中,我们使用表“Tender”中的数据,将展示它 -示例mysql> select * fro...
    99+
    2023-10-22
  • Java中什么情况会导致内存泄漏
    这篇文章主要讲解了“Java中什么情况会导致内存泄漏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中什么情况会导致内存泄漏”吧!概念内存泄露:指程序中动态分配内存给一些临时对象,但对...
    99+
    2023-06-16
  • mysql中什么情况会导致索引失效
    这篇文章主要为大家展示了“mysql中什么情况会导致索引失效”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysql中什么情况会导致索引失效”这篇文章吧。为了讲解以下索引内容,我们先建立一个临时...
    99+
    2023-06-25
  • java中什么情况下使用ArrayList和LinkedList?
    什么情况用ArrayList or LinkedList呢ArrayList 和 LinkedList 是 Java 集合框架中用来存储对象引用列表的两个类。ArrayList 和 LinkedList 都实现 List 接口。先对List...
    99+
    2016-08-06
    java教程 ArrayList LinkedList
  • MongoDB中什么情况下索引会选择策略
    这篇“MongoDB中什么情况下索引会选择策略”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MongoDB中什么情况下索引会...
    99+
    2023-06-29
  • 浅谈Mysql在什么情况下会使用内部临时表
    union执行 为了便于分析,使用一下sql来进行举例 CREATE TABLE t1 ( id INT PRIMARY KEY, a INT, b INT, IN...
    99+
    2024-04-02
  • 什么情况下会使用云服务器容灾备用方案
    什么情况下会使用云服务器容灾备用方案?在当今数字化时代,对于企业和组织而言,保障业务的连续性和数据的安全性至关重要。作为一种有效的高可用性解决方案,云服务器容灾备用方案正受到越来越多企业的青睐。本文将探讨在什么情况下需要使用云服务器容灾备...
    99+
    2024-01-23
    云服务器容灾备用方案 云服务器灾备方案 什么情况下会使用云服务器容灾备用方案 云服务器知识
  • 什么情况下需要使用redis
    这篇文章给大家分享的是有关什么情况下需要使用redis的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。redis是一个key-value存储系统。和Memcached类似,它支持存...
    99+
    2024-04-02
  • 什么情况下使用Adapter模式
    本篇内容主要讲解“什么情况下使用Adapter模式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么情况下使用Adapter模式”吧!适用性以下情况使用Adapter模式• 你想使用一个已经存在...
    99+
    2023-06-19
  • 什么情况下停止使用golang
    在现代编程领域中,Golang (又称 Go) 已经成为一个热门的编程语言。Golang 的设计目标是为了创建高效、可读性强、易于维护和编写的编程语言。它让编程变得更加简单,且在大规模高并发的应用程序开发上表现良好。然而,我们也需要看到问题...
    99+
    2023-05-14
  • java项目中什么情况下HashCode会出现重复
    java项目中什么情况下HashCode会出现重复?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java的缺省算法:  public int&...
    99+
    2023-05-31
    java hashcode 情况下
  • 怎么在Win10系统中查看流量使用情况
    怎么在Win10系统中查看流量使用情况?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 方法步骤  1、首先按Win+i打开“设置”界面,点击“网络和Internet”选项。  ...
    99+
    2023-06-13
  • 在什么情况下使用Builder模式
    今天小编给大家分享一下在什么情况下使用Builder模式的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。适用性在以下情况使用B...
    99+
    2023-06-19
  • java闭包在什么情况下使用
    闭包在以下情况下使用: 当一个方法需要访问外部作用域的变量时,可以使用闭包。闭包可以将变量保存在函数内部,并且可以在函数外部访问...
    99+
    2023-10-27
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作