Go   发布时间:2022-04-13  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Go内存逃逸分析大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

Go的内存逃逸及逃逸分析

Go的内存逃逸

分析内存逃逸之前要搞清楚一件事 我们编写的程序中的函数局部变量默认是存放在栈上的(补充一点堆上存储的数据的指针 是存放在栈上的 因为指针的大小是可以提前预知的 还有就是Go的基本类型也是存放在栈内的), 而其余的变量是存在堆上的, 栈是由操作系统层面控制 进行内存空间的释放 , 堆默认是程序控制的 像c c++ 是需要标明释放内存空间的位置 , 栈的运行速度远大于堆 . 拥有GC的高级语言回收的便是堆中的内容@H_696_11@

  • Go编译器查看内存逃逸的结果 go build -gcflags=-m xxx.go
  • 发生内存逃逸的场景
  1. 函数返回局部变量是一个指针变量
# 
type User struct {
  	Name String
}

func name(s String) *User {
	u := new(User)  # 这个变量的类型是 *User 指针变量
	u.Name = s

	return u
}

func main() {

	user := name("kuQi")
	fmt.Println(user)
}


# command-line-arguments
./main.go:9:6: can inline name
./main.go:18:14: inlining call to name
./main.go:19:13: inlining call to fmt.Println
./main.go:9:11: leaking param: s
./main.go:10:10: new(User) escapes to heap  // 造成逃逸
./main.go:18:14: new(User) escapes to heap  // 造成逃逸
./main.go:19:13: []interface {}{...} does not escape
<autogenerated>:1: leaking param content: .this


2.interface的动态类型造成的内存逃逸@H_696_11@

// fmt.Println 接受的参数就是interface动态类型 编译器很难确定接收变量的类型 所有会将123这个变量逃逸到堆

func main() {

	fmt.Println(123)
}


# command-line-arguments
./main.go:16:6: can inline main
./main.go:20:13: inlining call to fmt.Println
./main.go:20:14: 123 escapes to heap
./main.go:20:13: []interface {}{...} does not escape
<autogenerated>:1: leaking param content: .this

3.闭包函数产生的内存逃逸@H_696_11@

// 因为函数也是一个指针类型 所以将匿名函数作为返回值时  也会产生内存逃逸 原理类似于 第一个 原因

func BiBao() func() String {

	return func() String {

		return "test"
	}

}

# command-line-arguments
./main.go:24:9: func literal escapes to heap:
./main.go:24:9:   flow: ~r0 = &{storage for func literal}:
./main.go:24:9:     from func literal (spill) at ./main.go:24:9
./main.go:24:9:     from return func literal (return) at ./main.go:24:2
./main.go:24:9: func literal escapes to heap

4.变量大小无法确定 或 栈空间不足 引发内存逃逸@H_696_11@

ulimit -a    // ulimit -a 可以看到我们的栈空间是8192
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       2784
-n: file descriptors                2560

// 超大切片超出栈空间 引发的内存逃逸
package main

func main() {
	s := make([]int, 10000, 10000)  // 创建一个超大切片
	for index, _ := range s {
		s[index] = index
	}
}

大佬总结

以上是大佬教程为你收集整理的Go内存逃逸分析全部内容,希望文章能够帮你解决Go内存逃逸分析所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: