范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

golang2021数据格式(88)Go语言变量逃逸分析

  在讨论变量生命周期之前,先来了解下计算机组成里两个非常重要的概念:堆和栈。
  什么是栈
  栈(Stack)是一种拥有特殊规则的线性表数据结构。
  1) 概念
  栈只允许从线性表的同一端放入和取出数据,按照后进先出(LIFO,Last InFirst  Out)的顺序,如下图所示。
   
  图:栈的操作及扩展
  往栈中放入元素的过程叫做入栈。入栈会增加栈的元素数量,最后放入的元素总是位于栈的顶部,最先放入的元素总是位于栈的底部。
   
  从栈中取出元素时,只能从栈顶部取出。取出元素后,栈的元素数量会变少。最先放入的元素总是最后被取出,最后放入的元素总是最先被取出。不允许从栈底获取数据,也不允许对栈成员(除了栈顶部的成员)进行任何查看和修改操作。
   
  栈的原理类似于将书籍一本一本地堆起来。书按顺序一本一本从顶部放入,要取书时只能从顶部一本一本取出。
  2) 变量和栈有什么关系
  栈可用于内存分配,栈的分配和回收速度非常快。下面的代码展示了栈在内存分配上的作用:
  func  calc(a, b int) int {
        var c int
        c = a * b
  var  x int
        x = c * 10
  return  x
    }
  代码说明如下:
  第 1 行,传入 a、b 两个整型参数。
  第 2 行,声明整型变量 c,运行时,c       会分配一段内存用以存储 c 的数值。
  第 3 行,将 a 和 b 相乘后赋值给 c。
  第 5 行,声明整型变量 x,x 也会被分配一段内存。
  第 6 行,让 c 乘以 10 后赋值给变量 x。
  第 8 行,返回 x 的值。
  上面的代码在没有任何优化的情况下,会进行变量 c 和 x 的分配过程。Go语言默认情况下会将 c 和 x  分配在栈上,这两个变量在 calc() 函数退出时就不再使用,函数结束时,保存 c 和 x  的栈内存再出栈释放内存,整个分配内存的过程通过栈的分配和回收都会非常迅速。
  什么是堆
  堆在内存分配中类似于往一个房间里摆放各种家具,家具的尺寸有大有小,分配内存时,需要找一块足够装下家具的空间再摆放家具。经过反复摆放和腾空家具后,房间里的空间会变得乱七八糟,此时再往这个空间里摆放家具会发现虽然有足够的空间,但各个空间分布在不同的区域,没有一段连续的空间来摆放家具。此时,内存分配器就需要对这些空间进行调整优化,如下图所示。
   
  图:堆的分配及空间
  堆分配内存和栈分配内存相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片。
  变量逃逸(Escape  Analysis)——自动决定变量分配方式,提高运行效率
  堆和栈各有优缺点,该怎么在编程中处理这个问题呢?在 C/C++  语言中,需要开发者自己学习如何进行内存分配,选用怎样的内存分配方式来适应不同的算法需求。比如,函数局部变量尽量使用栈,全局变量、结构体成员使用堆分配等。程序员不得不花费很长的时间在不同的项目中学习、记忆这些概念并加以实践和使用。
   
  Go语言将这个过程整合到了编译器中,命名为"变量逃逸分析"。通过编译器分析代码的特征和代码的生命周期,决定应该使用堆还是栈来进行内存分配。
  1) 逃逸分析
  通过下面的代码来展现Go语言如何使用命令行来分析变量逃逸,代码如下:
  package  main
  import  "fmt"
  //  本函数测试入口参数和返回值情况
    func dummy(b int) int {
  //  声明一个变量c并赋值
        var c int
        c = b
  return  c
    }
  //  空函数, 什么也不做
    func void() {
    }
  func  main() {
  //  声明a变量并打印
        var a int
  //  调用void()函数
        void()
  //  打印a变量的值和dummy()函数返回
        fmt.Println(a, dummy(0))
    }
  代码说明如下:
  第 6 行,dummy()       函数拥有一个参数,返回一个整型值,用来测试函数参数和返回值分析情况。
  第 9 行,声明变量       c,用于演示函数临时变量通过函数返回值返回后的情况。
  第 16       行,这是一个空函数,测试没有任何参数函数的分析情况。
  第 23 行,在 main() 中声明变量 a,测试       main() 中变量的分析情况。
  第 26 行,调用 void()       函数,没有返回值,测试 void() 调用后的分析情况。
  第 29 行,打印 a 和 dummy(0)       的返回值,测试函数返回值没有变量接收时的分析情况。
  接着使用如下命令行运行上面的代码:
  go run -gcflags  "-m -l" main.go
  使用 go run 运行程序时,-gcflags 参数是编译参数。其中 -m 表示进行内存分配分析,-l  表示避免程序内联,也就是避免进行程序优化。
   
  运行结果如下:
  #  command-line-arguments
  ./main.go:29:13: a  escapes to heap
  ./main.go:29:22:  dummy(0) escapes to heap
  ./main.go:29:13: main  ... argument does not escape
  0 0
  程序运行结果分析如下:
  第 2 行告知"代码的第 29 行的变量 a       逃逸到堆"。
  第 3 行告知"dummy(0) 调用逃逸到堆"。由于       dummy() 函数会返回一个整型值,这个值被 fmt.Println 使用后还是会在 main() 函数中继续存在。
  第 4 行,这句提示是默认的,可以忽略。
  上面例子中变量 c 是整型,其值通过 dummy() 的返回值"逃出"了 dummy() 函数。变量 c  的值被复制并作为 dummy() 函数的返回值返回,即使变量 c 在 dummy() 函数中分配的内存被释放,也不会影响 main() 中使用  dummy() 返回的值。变量 c 使用栈分配不会影响结果。
  2) 取地址发生逃逸
  下面的例子使用结构体做数据,来了解结构体在堆上的分配情况,代码如下:
  package  main
  import  "fmt"
  //  声明空结构体测试结构体逃逸情况
    type Data struct {
    }
  func  dummy() *Data {
        // 实例化c为Data类型
        var c Data
  //返回函数局部变量地址
        return &c
    }
  func  main() {
        fmt.Println(dummy())
    }
  代码说明如下:
  第 6 行,声明一个空的结构体做结构体逃逸分析。
  第 9 行,将 dummy() 函数的返回值修改为       *Data 指针类型。
  第 11 行,将变量 c 声明为 Data 类型,此时       c 的结构体为值类型。
  第 14 行,取函数局部变量 c 的地址并返回。
  第 18 行,打印 dummy() 函数的返回值。
  执行逃逸分析:
  go run -gcflags  "-m -l" main.go
  #  command-line-arguments
  ./main.go:15:9: &c  escapes to heap
  ./main.go:12:6: moved  to heap: c
  ./main.go:20:19:  dummy() escapes to heap
  ./main.go:20:13: main  ... argument does not escape
  &{}
  注意第 4 行出现了新的提示:将 c 移到堆中。这句话表示,Go 编译器已经确认如果将变量 c  分配在栈上是无法保证程序最终结果的,如果这样做,dummy() 函数的返回值将是一个不可预知的内存地址,这种情况一般是 C/C++  语言中容易犯错的地方,引用了一个函数局部变量的地址。
   
  Go语言最终选择将 c 的 Data 结构分配在堆上。然后由垃圾回收器去回收 c 的内存。
  3) 原则
  在使用Go语言进行编程时,Go语言的设计者不希望开发者将精力放在内存应该分配在栈还是堆的问题上,编译器会自动帮助开发者完成这个纠结的选择,但变量逃逸分析也是需要了解的一个编译器技术,这个技术不仅用于Go语言,在  Java 等语言的编译器优化上也使用了类似的技术。
   
  编译器觉得变量应该分配在堆和栈上的原则是:
  变量是否被取地址;
  变量是否发生逃逸。

燕氏观点山西高校之晋中学院晋中学院(JinzhongUniversity)坐落于三晋腹地晋商故里晋中市榆次区,是一所山西省省属的全日制多科性本科院校。基本信息中文名晋中学院所属地区山西省晋中市外文名称Jin中国市场卖不动?特斯拉我怕不够卖意料之外的暴跌。8月10日,乘联会发布的中国汽车销量数据显示,7月特斯拉批发销量达3。29万辆,同比增长199。截止7月,特斯拉累计销售超过20万辆,达到205,763辆。其中,出产线转移股权生变,情怀已逝的广汽菲克不想努力了不想努力了。今天,广汽菲克公众号推送的一则消息,让敏感的扉旅汽车小编不禁好奇动作这么快。点进一看,虚惊一场,只是产品推介而已。不得不说,广汽菲克心真大,在传出产线转移股权生变的当下公益帮扶长安在行动,朱华荣上阵给酉阳茶油代言公益扶贫国企担当,长安汽车在行动!2021年7月9日,以爱有新益,有你更好为主题的长安汽车响应乡村振兴助力酉阳茶油品牌专场签约仪式,在重庆市酉阳县举办。在江北区委区政府酉阳县委县政欧尚X7PLUS车模任性送,给新车上市再添一把火随着欧尚X7PLUS预售的日期越来越近,新车也紧锣密鼓开启一系列活动。继当红PLUS炼成记的性能开箱封测顺利完成后,8月18日,欧尚汽车董事长亲自带货,8大官方平台与500家经销商粤港澳车展明日开幕,盘点最值得期待的几款新车一年一度的粤港澳车展又到来了!此次2021粤港澳大湾区车展,将于本周六在深圳会展中心举办。往年都是定在6月份举办粤港澳车展,今年由于南方地区的疫情原因,本次车展调整到了7月份。当然凡尔赛C5X凡而不装,14。37万起入门即豪华你想找一个又高又帅又温柔体贴还有钱的男朋友不一定好找,但是想要找一台兼顾操控和舒适,可乘可野,可甜可咸的车型,现在就有一款凡尔赛C5X。这是8月9日东风雪铁龙凡尔赛大会上的扎心金句年销80万辆造车新势力Top3?零跑你清醒一点不一般的目标。7月15日,零跑汽车举行了零跑2。0战略发布会,在会上,零跑科技联合创始人总裁吴保军宣布,零跑汽车目标在2023年进入造车新势力Top3,以及目标2025年的年销量突混血法拉利?全新大众凌渡高级了近日全新一代大众凌渡的曝光,让不少国内车友大户惊叹。设计风格翻天覆地的转变,与此前的大众家族套娃式外观完全不一样。据扉旅汽车小编获悉,新车将在今年底上市。在不少网友看到国内申报图的钓鱼需要开皮卡?长城炮是路亚钓鱼玩钓鱼,你还少一辆长城炮。为什么?钓鱼为什么需要长城炮?此钓鱼非彼钓鱼,长城炮在路亚钓鱼项目上又出圈了。路亚起源于20世纪初期,取名于Lure的音译,与传统钓鱼不同,是通过模仿弱小15万元的国产电动车小鹏P5,对标特斯拉Model32030万元的价格,对于一台品控稍高的国产电动车来说,可能多少会让人觉得价格有那么一点偏高,毕竟这个价位都能买辆合资车了。例如小鹏P7就是一个鲜明的例子,虽然车的品质都不错,但是接
为什么索尼手机没落了?提起索尼公司的大名,可谓是无人不知无人不晓,大家都说索尼大法好,乃至于全世界各地都有索尼的信仰粉!索尼是世界视听电子游戏通讯产品和信息技术等领域的先导者,是世界最早便携式数码产品的新机推荐,OPPOReon7,使用半个月,感觉好极了对于OPPO,vivo,作为女性玩家,一直是很有好感的。似乎它也特别照顾女性朋友,当然男性朋友也还是照顾的,先看看基本参数8256的存储组合,对于拍照大咖,也可以存储足够的照片,高到底是iphone好用还是安卓好用最近总是能在头条看到朋友问苹果好还是安卓好,各种对比神仙打架,我也是想发一篇文章说一说我的个人见解,欢迎大家评论区一起讨论,一起喷我,我是一直用安卓的人,突发奇想买了iphone,这三款SUV不仅跑得快还不怎么费钱!重要的是看起来很贵2530万左右的预算想买纯电动车SUV,大家似乎第一时间想到的就只有特斯拉ModelY。但其实在这个价位,有更多被低估的纯电SUV,有传统的合资品牌,也有新势力品牌,它们分别是,极拍得远更要拍得好,Magic3Pro13Pro长焦对比如今,手机影像系统被越来越多的厂商所重视,拍摄也逐渐成为了用户评定手机是否优秀的条件之一。相信,大多数用户的理想状态是大片直出的效果,仅凭这一点就对手机的软件算法有着极高的要求。而选手机买128G的还是256GB的?内存对于手机来说非常重要,小编建议直接买256GB的,为什么呢?因为就目前发布的手机而言,大部分手机128GB和256GB之间相差的就是两三百块钱,但是体验可不是两三百块钱可以买到ECMAScript5中如何定义接口接口和抽象类是静态面向对象编程语言的概念,如何在ES5中模拟接口和抽象类,这需要程序员有意识的养成良好的编码习惯,下面我们一起来展示一下接口如何定义接口的定义(模拟发布订阅模式下的接连拿下大订单!传闻泰科技获三星2022年约4000万台手机ODM订单12月15日消息,手机产业链人士透露,近期,三星2022年给手机ODM厂商的订单已释放出来,数量达60007000万台。这次三星给ODM厂商释放的订单主要落在了闻泰科技与华勤技术手Linux之mv命令mv是move的缩写,可以用来移动文件或者重命名文件名,经常用来备份文件或者目录。命令格式mv选项源文件或者目录目标文件或者目录命令功能mv命令中第二个参数类型的不同(是目标文件还谁在撒谎张同学的手机竟然不是OPPO恭喜张同学的视频走上了可持续发展之路,手机广告也和自己视频农村青年也很搭,没违和感。但是很多自媒体说张同学原来是使用OPPO手机拍摄的短视频,捂脸但是为何我看得央视记者采访时候,张如何区分次旗舰旗舰机与高端机?其实不难,逐一分析自然能理解很多手机厂商喜欢混淆视听,把自己发布的次旗舰机当作是旗舰机来卖,把旗舰机说成是高端机,并且还把低价当作是一种优势,然而事实上,有些次旗舰可能是中端机,而有些旗舰机可能是次旗舰,而很