Go的内存逃逸及逃逸分析

Go的内存逃逸

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

  • 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的动态类型造成的内存逃逸

// 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.闭包函数产生的内存逃逸

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

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.变量大小无法确定 或 栈空间不足 引发内存逃逸

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内存逃逸分析的更多相关文章

  1. Golang逃逸分析

    Golang逃逸分析 介绍逃逸分析的概念,go怎么开启逃逸分析的log. 以下资料来自互联网,有错误之处,请一定告之. sheepbao 2017.06.10 什么是逃逸分析 wiki上的定义 In ...

  2. JVM中启用逃逸分析

    -XX:+DoEscapeAnalysis 逃逸分析优化JVM原理我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量 ...

  3. JVM笔记-逃逸分析

    参考: http://www.iteye.com/topic/473355http://blog.sina.com.cn/s/blog_4b6047bc01000avq.html 什么是逃逸分析(Es ...

  4. Go变量逃逸分析

    目录 什么是逃逸分析 为什么要逃逸分析 逃逸分析是怎么完成的 逃逸分析实例 总结 写过C/C++的同学都知道,调用著名的malloc和new函数可以在堆上分配一块内存,这块内存的使用和销毁的责任都在程 ...

  5. JVM逃逸分析

    开启逃逸分析: -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m 关闭逃逸分析: -server -XX:-DoEsca ...

  6. 逃逸分析(Escape Analysis)

    一.什么是逃逸 逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到:这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量 ...

  7. 深入理解Java中的逃逸分析

    在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. ...

  8. Go 语言机制之逃逸分析

    https://blog.csdn.net/weixin_38975685/article/details/79788254   Go 语言机制之逃逸分析 https://blog.csdn.net/ ...

  9. JVM的逃逸分析

    我们都知道Java中的对象默认都是分配到堆上,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存.如果堆中对象数量太多,回收对象还有整理内存,都会会带来时间上的消耗, ...

随机推荐

  1. (转)Make 命令

    Make 命令 代码变成可执行文件,叫做编译(compile):先编译这个,还是先编译那个(即编译的安排),叫做构建(build). Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目 ...

  2. 【C++】自定义数据类型

    自定义数据类型 标签:c++ 目录 自定义数据类型 一.结构体 定义方法: 特点: 成员访问方式: 初始化: 结构数组 指针和动态内存分配: 结构变量作为函数参数: 二.联合 定义方法: 特点: 举例 ...

  3. 使用Cesium Stories在3D Tilesets中检查Features

    Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 我们创建了3D Tiles用以流式化.可视化和分析大量的三维内容 ...

  4. 微信小程序-国际化(miniprogram-i18n)

    前情提要 最近维护了一个微信小程序的老项目,维护的其中一项是添加国际化.由于踩了蛮多坑,所以就有了这篇文档!!! miniprogram-i18n 对除小程序外的其他框架开发做过国际化的朋友来说i18 ...

  5. 实习之bii--配置esxi重启时,虚拟机也跟随重启

    由于初创环境不稳定又是服务器会重启,而内部安装的多部虚拟机并不默认跟随启动,需要设置,方法如下: 1.在本地通过vsphere client 登录到esxi的服务器上,然后点击配置找到虚拟机启动/关机 ...

  6. golang中的pair

    package main import "fmt" type Reader interface { ReadBook() } type Writer interface { Wri ...

  7. Kubernetes中部署wordpress+mysql(六)

    经过前面的内容其实对k8s已经有了服务迁移的能力了,下面这篇文章主要是用来搭建一些后面要用的组件 一.创建wordpress命名空间 kubectl create namespace wordpres ...

  8. 解决matplotlib中文不显示问题

    在导入库时添加如下几行代码 from pylab import mpl mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体 mpl.rcPa ...

  9. mysql获取表中的字段名

    转载请注明来源:https://www.cnblogs.com/hookjc/ SELECT COLUMN_NAME FROM 'information_schema'.'COLUMNS' where ...

  10. LNMP平台的redis对接安装

    LNMP平台的redis对接安装 目录 LNMP平台的redis对接安装 一.安装LNMP的各个组件 二.安装redis服务 三.安装redis扩展 四.修改php配置文件 五.测试连接 一.安装LN ...