IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Go语言变量逃逸分析 -> 正文阅读

[C++知识库]Go语言变量逃逸分析

什么是逃逸分析

在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法——分析在程序的哪些地方可以访问到指针。也是就是说逃逸分析是解决指针作用范围的编译优化方法。编程中常见的两种逃逸情景:

  • 函数中局部对象指针被返回(不确定被谁访问)
  • 对象指针被多个子程序(如线程 协程)共享使用

为什么要做逃逸分析

开始我们提到go语言中对象内存的分配不是由语言运算符或函数决定,而是通过逃逸分析来决定。为什么要这么干呢?其实说到底还是为了优化程序。函数中生成一个新对象:

  • 如果分配到栈上,待函数返回资源就被回收了
  • 如果分配到堆上,函数返回后交给gc来管理该对象资源

栈资源的分配及回收速度比堆要快,所以逃逸分析最大的好处应该是减少了GC的压力。

使用命令go build -gcflags “-m -l” test.go可以分析变量是否逃逸

逃逸分析的场景

指针逃逸

典型的指针逃逸案例,返回局部变量的指针

package main

func test2() *int {
	c1 := 20
	return &c1
}

func main() {
	c2 := test2()
	println(*c2)
}

栈空间不足逃逸

package main

func main() {
	t := make([]int, 1000)
	m := make([]int, 10000)

	t[0] = 1
	m[0] = 1
}

/*
make([]int, 1000) does not escape
make([]int, 10000) escapes to heap
*/

闭包引用逃逸

package main

func Fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return a
	}
}

func main() {
	f := Fibonacci()
	for i := 0; i < 5; i++ {
		println(f())
	}
}

动态类型逃逸

当对象不确定大小或者被作为不确定大小的参数时发生逃逸。t的大小是个变量所以会逃逸到堆上。size作为interface{}参数逃逸到堆上

package main

func main() {
	var size int = 10
	t := make([]int, size)
	m := make([]int, 10)
	for i := 0; i < size; i++ {
		t[i] = i
		m[i] = i
	}
}

/*
make([]int, size) escapes to heap
make([]int, 10) does not escape
*/

切片或map赋值

在给切片或者map赋值对象指针(与对象共享内存地址时),对象会逃逸到堆上。但赋值对象值或者返回对象值切片是不会发生逃逸的。

package main

func test3() {
	var i = 10
	var j = 10
	s2 := make([]*int, 2)
	m2 := make(map[int]*int)

	s2[0] = &i
	m2[0] = &j
}

func main() {
	test3()
}

/*
./test.go:442:6: moved to heap: i
./test.go:443:6: moved to heap: j
./test.go:445:12: make([]*int, 2) does not escape
./test.go:447:12: make(map[int]*int) does not escape
*/

其实内存逃逸还有其他场景,所以在平时开发中尽量去避免这些情况,可以有效地提高程序的运行效率

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:13:21  更:2022-03-15 22:15:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:56:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码