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. Julia语言介绍

    官网:https://julialang.org/ 中文社区:https://cn.julialang.org/ Julia 是一个面向科学计算的高性能动态高级程序设计语言. 首先定位是通用编程语言, ...

  2. 聊聊dubbo协议2

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 在<聊聊dubbo协议>中介绍了attachments在consumer和prov ...

  3. 【刷题-LeetCode】205. Isomorphic Strings

    Isomorphic Strings Given two strings *s* and *t*, determine if they are isomorphic. Two strings are ...

  4. promise的队列,宏任务,微任务,同步任务

    // promise里面有一个特别的任务,就是微任务 // 同步任务>微任务>宏任务 setTimeout(() => { console.log("setTimeout& ...

  5. Servlet Listener(监听器)

    监听器 Listener 是一个实现特定接口的 Java 程序,这个程序专门用于监听另一个 Java 对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即自动执行.监听器的相关概 ...

  6. Filter-完整的用户登录和权限检查

    Filter过滤器的使用步骤: 1,编写一个类去实现Filter接口 2,实现拦截(过滤)方法doFilter() 3,到web.xml中配置Filter的拦截路径 补充login.jsp登录页面 编 ...

  7. zabbix_proxy3.4安装

    server ip:172.16.2.116 proxy ip:172.16.2.241 1.创建proxy数据库,proxy用户 mysql> create database zabbix_p ...

  8. http协议和https协议的区别

    超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...

  9. Net6 DI源码分析Part1 ServiceCollection、ServiceDescriptor、ServiceLifetime、IServiceProvider

    ServiceCollection.ServiceDescriptor.ServiceLifetime.IServiceProvider Microsoft.Extensions.Dependency ...

  10. 截取一段时间内的log日志

    可以使用sed命令对log文件进行抽取操作:1,sed查看某时间段到现在的系统日志:sed -n '/May 20 17/,$p' /var/log/messages | less2,sed 截选时间 ...