首页 > 其他分享 >逃逸分析案例

逃逸分析案例

时间:2023-12-12 18:35:11浏览次数:23  
标签:分析 func int fmt 案例 逃逸 str main

1.函数返回局部指针变量

func Add(x,y int) *int {
 res := 0
 res = x + y
 return &res
}
func main()  {
 Add(1,2)
}

函数返回局部变量是一个指针变量,该函数执行结束,对应栈帧就会销毁,但是引用返回到函数外部,如果外部解析地址,就会导致程序访问非法内存,所以经过编辑器分析过后将其在堆上分配

2.interface类型逃逸

1)interface产生逃逸

func main()  {
   str := "荔枝"
   fmt.Println(str)
}

str是main的一个局部变量,传给 fmt.Printl()之后逃逸,因为fmt.Println()的入参是interface{}类型,那么编译期间就很难确定参数类型

2)指向栈对象的指针不能在堆中

func main()  {
   str := "苏珊"
   fmt.Println(&str)
}

这次str也逃逸到堆上面了,在堆上面进行分配,因为入参是interface,变量str的地址被以实参的方式传入fmt.Println被装箱到一个interface{}

装箱的形参变量要在堆上分配,但是还需要存储一个栈上的地址,这和之前说的第一条不符,所以str也会分配到堆上

3.闭包产生逃逸

func Increase() func() int {
 n := 0
 return func() int {
  n++
  return n
 }
}

func main() {
 in := Increase()
 fmt.Println(in()) // 1
}

因为函数是指针类型,所以匿名函数当做返回值产生逃逸,匿名函数使用外部变量n,这个n会一直存在知道in被销毁

4. 变量大小不确定及栈空间不足引发逃逸

import (
    "math/rand"
)

func LessThan8192()  {
    nums := make([]int, 100) // = 64KB
    for i := 0; i < len(nums); i++ {
        nums[i] = rand.Int()
    }
}


func MoreThan8192(){
    nums := make([]int, 1000000) // = 64KB
    for i := 0; i < len(nums); i++ {
        nums[i] = rand.Int()
    }
}


func NonConstant() {
    number := 10
    s := make([]int, number)
    for i := 0; i < len(s); i++ {
        s[i] = i
    }
}

func main() {
    NonConstant()
    MoreThan8192()
    LessThan8192()
}

栈空间足够不会发生逃逸,但是变量过大,已经超过栈空间,会逃逸到堆上

总结
1)逃逸分析在编译阶段确定哪些变量可以分配在栈中,哪些变量分配在堆上
2)逃逸分析减轻了GC压力,提高程序的运行速度
3)栈上内存使用完毕不需要GC处理,堆上内存使用完毕会交给GC处理
4)函数传参时对于需要修改原对象值,或占用内存比较大的结构体,选择传指针;对于只读的占用内存较小的结构体,直接传值能够获得更好的性能
5)根据代码具体分析,尽量减少逃逸代码,减轻GC压力,提高性能

标签:分析,func,int,fmt,案例,逃逸,str,main
From: https://www.cnblogs.com/beatle-go/p/17897555.html

相关文章

  • Quick BI 数据分析 - Alibaba Cloud的文档PDF
     下载地址:https://static-aliyun-doc.oss-cn-hangzhou.aliyuncs.com/download%2Fpdf%2F164487%2F%25E6%2595%25B0%25E6%258D%25AE%25E5%2588%2586%25E6%259E%2590_intl_zh-CN.pdf      ......
  • 深圳CPDA数据分析师认证招生简章一览
    CPDA数据分析师认证是大数据方面的认证,助力数据分析人员打下扎实的数据分析基础知识功底,为入门数据分析保驾护航。帮助数据分析人员掌握系统化的数据分析思维和方法论,提升工作效率和决策能力,遇到问题能够举一反三,为大部分决策难题提供解决方案。帮助数据分析人员掌握几种通用的数据......
  • 秦疆的Java课程笔记:65 面向对象 创建对象内存分析
    先写两个类//创建一个Pet类==============================packageOOP.demo;publicclassPet{publicStringname;publicintage;publicvoidshout(){System.out.println("喵~~");}}//主程序Application================......
  • 从根上理解elasticsearch(lucene)查询原理(2)-lucene常见查询类型原理分析
    大家好,我是蓝胖子,在上一节我提到要想彻底搞懂elasticsearch慢查询的原因,必须搞懂lucene的查询原理,所以在上一节我分析了lucene查询的整体流程,除此以外,还必须要搞懂各种查询类型内部是如何工作,比如比较复杂的查询是将一个大查询分解成了小查询,然后通过对小查询的结果进行合并得到......
  • 云电脑:DPU简介及分析
    本文分享自天翼云开发者社区《云电脑:DPU简介及分析》,作者:大利随着云计算技术的快速发展,云电脑作为一种基于云计算技术的虚拟化电脑,正在逐渐受到广泛关注。然而,云电脑在实现过程中面临着许多挑战,如计算资源的有限性、数据传输的瓶颈等。为了解决这些问题,一种新型的设备——数据处......
  • 数仓调优实践丨多次关联发散导致数据爆炸案例分析改写
    本文分享自华为云社区《GaussDB(DWS)性能调优:求字段全体值中大于本行值的最小值——多次关联发散导致数据爆炸案例分析改写》,作者:Zawami。1、【问题描述】 语句中存在同一个表多次自关联,且均为发散关联,数据爆炸导致性能瓶颈。2、【原始SQL】explainverboseWITHTMPAS......
  • redis加锁逻辑分析
     publicbooleantryLock(longwaitTime,longleaseTime,TimeUnitunit)throwsInterruptedException{//省略部分代码time-=System.currentTimeMillis()-current;if(time<=0){acquireFailed(waitTime,unit,threadId);......
  • 递归函数复杂度分析
    在分析递归函数的时间复杂度时,我们需要考虑以下因素:每次递归调用的工作量。递归的深度(调用的次数)。每一层递归中的分支数。通常,我们使用递归树来分析递归算法的时间复杂度。具体的时间复杂度取决于递归算法的实现细节。我们来看一个简单的例子:计算斐波那契数列的递归实现。......
  • 聊天记录年度报告一览无余:轻松多格式导出永久保存,深度智能分析
    聊天记录年度报告一览无余:轻松多格式导出永久保存,深度智能分析1.功能简介效果展示一个用于提取微信聊天记录的工具,支持将聊天记录导出成HTML、Word、CSV文档,以实现永久保存。此外,该工具还具有对聊天记录进行分析的功能,可以生成年度聊天报告,帮助用户更好地了解和回顾与他人的沟通......
  • Guardrails for Amazon Bedrock 基于具体使用案例与负责任 AI 政策实现定制式安全保障
    作为负责任的人工智能(AI)战略的一部分,您现在可以使用 GuardrailsforAmazonBedrock(预览版),实施专为您的用例和负责任的人工智能政策而定制的保障措施,以此促进用户与生成式人工智能应用程序之间的安全交互。亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术......