欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang內(nèi)存逃逸的學(xué)習(xí)筆記

 更新時(shí)間:2024年05月05日 09:03:07   作者:淡墨@~無(wú)痕  
內(nèi)存逃逸是 Go 語(yǔ)言編程中一個(gè)特別需要注意的問(wèn)題,會(huì)影響到程序的性能和穩(wěn)定性,本文主要介紹了golang內(nèi)存逃逸的學(xué)習(xí)筆記,感興趣的可以了解一下

逃逸分析( Escape analysis) 是指由編譯器決定內(nèi)存分配的位置, 不需要程序員指定。 函數(shù)中申請(qǐng)一個(gè)新的對(duì)象。

  • 如果分配在棧中, 則函數(shù)執(zhí)行結(jié)束可自動(dòng)將內(nèi)存回收;
  • 如果分配在堆中, 則函數(shù)執(zhí)行結(jié)束可交給GC( 垃圾回收) 處理;

內(nèi)存逃逸策略

每當(dāng)函數(shù)中申請(qǐng)新的對(duì)象, 編譯器會(huì)跟據(jù)該對(duì)象是否被函數(shù)外部引用來(lái)決定是否逃逸:

  • 如果函數(shù)外部沒(méi)有引用, 則優(yōu)先放到棧中
  • 如果函數(shù)外部存在引用, 則必定放到堆中;

注意, 對(duì)于函數(shù)外部沒(méi)有引用的對(duì)象, 也有可能放到堆中, 比如內(nèi)存過(guò)大超過(guò)棧的存儲(chǔ)能力。

逃逸場(chǎng)景分析

指針逃逸

Go可以返回局部變量指針, 這其實(shí)是一個(gè)典型的變量逃逸案例, 示例代碼如下:

package main

type Student struct {
	Name string
	age int
}

func NewStudent(name string, age int) *Student {
	stu := new(Student)
	stu.Name = name
	stu.age = age
	return stu
}
func main()  {
	NewStudent("abcd", 24)
}

函數(shù)NewStudent()內(nèi)部stu為局部變量, 其值通過(guò)函數(shù)返回值返回, stu本身為一指針, 其指向的內(nèi)存地址不會(huì)是棧而是堆, 這就是典型的逃逸案例。

通過(guò)編譯參數(shù)-gcflags=-m可以查年編譯過(guò)程中的逃逸分析:
運(yùn)行結(jié)果: 請(qǐng)注意運(yùn)行結(jié)果中出現(xiàn)了escapes to heap,也就是發(fā)生了內(nèi)存逃逸現(xiàn)象。

在這里插入圖片描述

??臻g不足逃逸

分析一下下面代碼會(huì)不會(huì)產(chǎn)生內(nèi)存逃逸現(xiàn)象

package main

type Student struct {
	Name string
	age int
}

func Slice()  {
	s := make([]int, 1000, 1000)
	for index, _ := range s {
		s[index] = index
	}
}
func main()  {
	Slice()
}

上面代碼Slice()函數(shù)中分配了一個(gè)1000個(gè)長(zhǎng)度的切片, 是否逃逸取決于棧空間是否足夠大。 直接查看編譯提示, 如下可見(jiàn)并沒(méi)有發(fā)生逃逸:

在這里插入圖片描述

但是如果長(zhǎng)度擴(kuò)大10倍呢?那情況會(huì)怎么樣?

package main

func Slice()  {
	s := make([]int, 10000, 10000)
	for index, _ := range s {
		s[index] = index
	}
}
func main()  {
	Slice()
}

結(jié)果:

在這里插入圖片描述

我們發(fā)現(xiàn)當(dāng)切片長(zhǎng)度擴(kuò)大到10000時(shí)就會(huì)逃逸。實(shí)際上當(dāng)??臻g不足以存放當(dāng)前對(duì)象時(shí)或無(wú)法判斷當(dāng)前切片長(zhǎng)度時(shí)會(huì)將對(duì)象分配到堆中

動(dòng)態(tài)類型逃逸

很多函數(shù)參數(shù)為interface類型, 比如fmt.Println(a …interface{}), 編譯期間很難確定其參數(shù)的具體類型,也人產(chǎn)生逃逸。 如下代碼所示:

package main

import "fmt"

func main()  {
	s := "abcd"
	fmt.Println(s)
}

結(jié)果:上述代碼s變量只是一個(gè)string類型變量, 調(diào)用fmt.Println()時(shí)會(huì)產(chǎn)生逃逸。

在這里插入圖片描述

閉包引用對(duì)象逃逸

相信刷題的同學(xué)對(duì)這代碼是十分的熟悉:

package main

import "fmt"

func Fibonacci() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a + b
		return a
	}
}
func main()  {
	res := Fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Printf("Print Result is %d\n" , res())
	}
}

這段代碼的運(yùn)行結(jié)果如下:

在這里插入圖片描述

但是Fibonacci()函數(shù)中原本屬于局部變量的a和b由于閉包的引用, 不得不將二者放到堆上, 以致產(chǎn)生逃逸:

在這里插入圖片描述

總結(jié)

  • 棧上分配內(nèi)存比在堆中分配內(nèi)存有更高的效率
  • 棧上分配的內(nèi)存不需要GC處理
  • 堆上分配的內(nèi)存使用完畢會(huì)交給GC處理
  • 逃逸分析目的是決定內(nèi)分配地址是棧還是堆
  • 逃逸分析在編譯階段完成

 到此這篇關(guān)于golang內(nèi)存逃逸的學(xué)習(xí)筆記的文章就介紹到這了,更多相關(guān)Golang內(nèi)存逃逸 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 減少 golang 二進(jìn)制文件大小操作

    減少 golang 二進(jìn)制文件大小操作

    這篇文章主要介紹了減少 golang 二進(jìn)制文件大小操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go語(yǔ)言占位符的使用

    Go語(yǔ)言占位符的使用

    本文主要介紹了Go語(yǔ)言占位符的使用,字符串占位符在fmt包的各種打印函數(shù)中使用,下面就一起來(lái)介紹一下,感興趣的可以了解一下
    2024-08-08
  • golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例

    golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例

    本文主要介紹了golang中set數(shù)據(jù)結(jié)構(gòu)的使用示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Golang定時(shí)器的2種實(shí)現(xiàn)方法與區(qū)別

    Golang定時(shí)器的2種實(shí)現(xiàn)方法與區(qū)別

    這篇文章主要給大家介紹了關(guān)于Golang定時(shí)器的2種實(shí)現(xiàn)方法與區(qū)別的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 如何在Go語(yǔ)言中靈活運(yùn)用匿名函數(shù)和閉包

    如何在Go語(yǔ)言中靈活運(yùn)用匿名函數(shù)和閉包

    這篇文章主要為大家介紹了如何在Go語(yǔ)言中靈活運(yùn)用匿名函數(shù)和閉包實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • golang高并發(fā)的深入理解

    golang高并發(fā)的深入理解

    golang從語(yǔ)言級(jí)別上對(duì)并發(fā)提供了支持,而且在啟動(dòng)并發(fā)的方式上直接添加了語(yǔ)言級(jí)的關(guān)鍵字。下面這篇文章主要給大家介紹了關(guān)于golang高并發(fā)的相關(guān)資料,需要的朋友可以參考下
    2019-03-03
  • Go語(yǔ)言包管理模式示例分析

    Go語(yǔ)言包管理模式示例分析

    這篇文章主要為大家介紹了Go語(yǔ)言包管理模式示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Golang對(duì)MongoDB數(shù)據(jù)庫(kù)的操作簡(jiǎn)單封裝教程

    Golang對(duì)MongoDB數(shù)據(jù)庫(kù)的操作簡(jiǎn)單封裝教程

    mongodb官方?jīng)]有關(guān)于go的mongodb的驅(qū)動(dòng),因此只能使用第三方驅(qū)動(dòng),mgo就是使用最多的一種。下面這篇文章主要給大家介紹了關(guān)于利用Golang對(duì)MongoDB數(shù)據(jù)庫(kù)的操作簡(jiǎn)單封裝的相關(guān)資料,需要的朋友可以參考下
    2018-07-07
  • GoLang并發(fā)機(jī)制探究goroutine原理詳細(xì)講解

    GoLang并發(fā)機(jī)制探究goroutine原理詳細(xì)講解

    goroutine是Go語(yǔ)言提供的語(yǔ)言級(jí)別的輕量級(jí)線程,在我們需要使用并發(fā)時(shí),我們只需要通過(guò) go 關(guān)鍵字來(lái)開(kāi)啟 goroutine 即可。這篇文章主要介紹了GoLang并發(fā)機(jī)制goroutine原理,感興趣的可以了解一下
    2022-12-12
  • Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法

    Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法

    這篇文章主要介紹了Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10

最新評(píng)論