国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

聊聊內(nèi)存中的Slice操作

開發(fā) 前端
操作系統(tǒng)、處理器架構(gòu)、Golang版本不同,均有可能造成相同的源碼編譯后運行時內(nèi)存地址、數(shù)據(jù)結(jié)構(gòu)不同。本文僅保證學(xué)習(xí)過程中的分析數(shù)據(jù)在當前環(huán)境下的準確有效性。

[[417663]]

本文主要關(guān)注 slice 的相關(guān)操作:

  1. 元素賦值(修改)
  2. make
  3. copy
  4. make and copy
  5. append

環(huán)境

  1. OS : Ubuntu 20.04.2 LTS; x86_64 
  2. Go : go version go1.16.2 linux/amd64 

聲明

操作系統(tǒng)、處理器架構(gòu)、Golang版本不同,均有可能造成相同的源碼編譯后運行時內(nèi)存地址、數(shù)據(jù)結(jié)構(gòu)不同。

本文僅保證學(xué)習(xí)過程中的分析數(shù)據(jù)在當前環(huán)境下的準確有效性。

代碼清單

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. func main() { 
  6.     var src = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 
  7.     src[3] = 100 
  8.     //src[13] = 200 
  9.     dst := makeSlice() 
  10.     makeSliceCopy(src) 
  11.     growSlice(src) 
  12.     copySlice(dst, src) 
  13.     sliceStringCopy([]byte("hello world"), "hello slice"
  14.  
  15. //go:noinline 
  16. func sliceStringCopy(slice []byte, s string) { 
  17.     copy(slice, s) 
  18.     PrintInterface(string(slice)) 
  19.  
  20. //go:noinline 
  21. func copySlice(dst []int, src []int) { 
  22.     copy(dst, src) 
  23.     PrintInterface(dst) 
  24.  
  25. //go:noinline 
  26. func growSlice(slice []int) { 
  27.     slice = append(slice, 11) 
  28.     PrintInterface(slice) 
  29.  
  30. //go:noinline 
  31. func makeSliceCopy(array []int) { 
  32.     slice := make([]int, 5) 
  33.     copy(slice, array) 
  34.     PrintInterface(slice) 
  35.  
  36. //go:noinline 
  37. func makeSlice() []int { 
  38.     slice := make([]int, 5) 
  39.     //slice := make([]int, 5, 10) 
  40.     //slice := make([]int, 10, 5) // "len larger than cap in make(%v)" 
  41.     return slice 
  42.  
  43. //go:noinline 
  44. func PrintInterface(v interface{}) { 
  45.     fmt.Println("it =", v) 

深入內(nèi)存

1. 元素賦值

該操作很簡單,直接通過偏移量定位元素內(nèi)存并賦值,對應(yīng)一條機器指令:

圖片

如果如下元素索引超過runtime.slice.cap, 則會panic。

  1. src[13] = 200 
圖片

查看可執(zhí)行程序,Golang編譯器發(fā)現(xiàn)代碼異常之后,直接使用runtime.panicIndex函數(shù)調(diào)用替換了元素賦值及之后的所有操作,退出程序。

圖片

這很令人好奇:明明編譯時期發(fā)現(xiàn)了代碼邏輯錯誤,但并沒有終止編譯過程,而是把它變成一個運行時異常。難道運行時異常更好嗎?

針對這個問題暫時沒有找到合理的答案,只能猜測這是編譯器為了應(yīng)對各種代碼場景的一個通用編譯處理邏輯,而不是僅僅為了處理本例中的情況。

2. make

使用make關(guān)鍵字動態(tài)創(chuàng)建 slice。編譯之后make會變成什么指令,視情況而定。

代碼清單中第42行的makeSlice函數(shù)編譯之后,對應(yīng)的機器指令如下:

圖片

可以看到,make關(guān)鍵字編譯之后,變成了 runtime.makeslice 函數(shù)調(diào)用,其實現(xiàn)如下:

  1. func makeslice(et *_type, len, cap int) unsafe.Pointer { 
  2.     // 計算需要分配的內(nèi)存字節(jié)數(shù) 
  3.     mem, overflow := math.MulUintptr(et.size, uintptr(cap)) 
  4.     if overflow || mem > maxAlloc || len < 0 || len > cap { 
  5.         mem, overflow := math.MulUintptr(et.size, uintptr(len)) 
  6.         if overflow || mem > maxAlloc || len < 0 { 
  7.             panicmakeslicelen() 
  8.         } 
  9.         panicmakeslicecap() 
  10.     } 
  11.  
  12.     // 直接分配內(nèi)存 
  13.     return mallocgc(mem, et, true

以上代碼非常簡單,有幾個判斷條件稍微解釋下:

(1)overflow表示元素大小和元素數(shù)量的乘積是否溢出,即是否大于64位無符號整數(shù)的最大值,肯定是不能大于的;

(2)maxAlloc的值為 0x1000000000000,實際上大多數(shù)64位處理器和操作系統(tǒng)的內(nèi)存可尋址范圍并不是64位,而是不超過48位,這是Golang一個內(nèi)存分配和校驗邏輯;

(3)len>cap時,Golang編譯器會進行檢查 ,編譯失敗。

另外,在Golang源碼中,有個 runtime.makeslice64 函數(shù),并沒有出現(xiàn)在編譯后的可執(zhí)行程序中。在 Go 編譯器代碼中看到應(yīng)該是和32位程序編譯相關(guān)。我們更關(guān)心64位程序,所以不再深究。

3. copy

代碼清單中第23行的copySlice函數(shù)編譯之后,對應(yīng)的機器指令如下:

圖片

將其翻譯為Golang偽代碼,大意如下:

  1. func copySlice(dst []int, src []int) { 
  2.     n := len(dst) 
  3.     if n  > len(src) { 
  4.         n = len(src) 
  5.     } 
  6.     if &dst[0] != &src[0] { 
  7.         runtime.memmove(&dst[0], &src[0], len(dst)*8) 
  8.     } 
  9.     PrintInterface(dst) 

仔細閱讀以上指令代碼,確定其邏輯與 runtime.slicecopy 函數(shù)相匹配,也就是說copy關(guān)鍵字編譯之后變成了runtime.slicecopy函數(shù)調(diào)用。但是編譯器對runtime.slicecopy函數(shù)進行了內(nèi)聯(lián)優(yōu)化,所以最終并不能看到直接的runtime.slicecopy函數(shù)調(diào)用。

在Golang中,copy關(guān)鍵字可以用于把 string 對象拷貝到[]byte對象中;因為字符串類型還沒有學(xué)習(xí)到,所以暫時擱置這種特殊情況。

4. make and copy

當make和copy兩個關(guān)鍵字一起使用時,又發(fā)生了新變化。

代碼清單中第35行的makeSliceCopy函數(shù)編譯之后,對應(yīng)的機器指令如下:

圖片

可以清楚的看到,當make和copy兩個關(guān)鍵字一起使用時,被Golang編譯器合并成了 runtime.makeslicecopy 函數(shù)調(diào)用。該函數(shù)源代碼邏輯非常清晰,此處不再贅述。

5. append

代碼清單中第29行的growSlice函數(shù)對已經(jīng)滿的 slice 進行 append 操作。

編譯之后,對應(yīng)的機器指令如下:

圖片

以上代碼邏輯是:首先進行l(wèi)en(slice)+1和cap(slice)比較,對已經(jīng)滿的 slice 進行 append 操作時,將觸發(fā)底層數(shù)組的長度擴增(分配新的數(shù)組),將其翻譯為Golang偽代碼,大意如下:

  1. func growSlice(slice []int) { 
  2.     if len(slice) + 1 > cap(slice) { 
  3.         slice = runtime.growslice(element_type_pointer, slice, 11) 
  4.     } 
  5.     // cap(slice) == 20 
  6.     slice[len(slice)] = 17 
  7.     PrintInterface(slice) 

runtime.growslice 函數(shù)的功能是:slice 進行append操作時,如果該slice已經(jīng)滿了,調(diào)用該函數(shù)重新分配底層數(shù)組進行擴容。

在本例中,

  1. 原 slice 的容量是10,調(diào)用runtime.growslice函數(shù)之后,容量變?yōu)?0。
  2. slice元素是 int 類型(element_type_pointer),關(guān)于該類型的分析可以閱讀內(nèi)存中的整數(shù) 。

通過以上學(xué)習(xí)研究,對slice的各種操作有了本質(zhì)上的了解,相信用起來更加得心應(yīng)手。

本文轉(zhuǎn)載自微信公眾號「Golang In Memory」

 

責任編輯:姜華 來源: Golang In Memory
相關(guān)推薦

2022-11-28 07:21:53

操作系統(tǒng)內(nèi)存管理

2021-03-28 13:54:31

操作系統(tǒng)內(nèi)存管理

2021-02-03 15:12:08

java內(nèi)存溢出

2021-08-12 14:19:14

Slice數(shù)組類型內(nèi)存

2021-12-16 06:52:33

C語言內(nèi)存分配

2022-11-30 08:19:15

內(nèi)存分配Go逃逸分析

2021-01-07 07:53:10

JavaScript內(nèi)存管理

2021-09-02 11:31:28

二叉搜索樹迭代法公共祖先

2023-11-17 11:40:51

C++內(nèi)存

2021-10-15 08:57:40

內(nèi)存容量

2021-09-10 08:18:31

Go語言字符串

2021-08-31 07:54:24

SQLDblink查詢

2024-04-26 00:00:00

Rust檢查器代碼

2023-11-09 11:56:28

MySQL死鎖

2021-07-07 12:01:48

iOS內(nèi)存對齊

2021-11-17 08:11:35

MySQL

2021-06-29 07:04:16

Sed常用操作

2020-05-09 13:49:00

內(nèi)存空間垃圾

2019-07-11 15:43:44

KVMKSM內(nèi)存

2023-11-29 10:26:52

分布式數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號

欧美日韩加勒比精品一区| 亚洲免费视频在线观看| 伊人久久av导航| 亚洲精品不卡在线观看 | 乱亲女秽乱长久久久| 激情小视频在线观看| 久久久美女毛片| 亚洲成人av动漫| 欧美.日韩.国产.一区.二区| 久久91精品国产91久久久| 欧美人体视频xxxxx| 午夜亚洲国产au精品一区二区| 国产婷婷一区二区三区| 国产精品三上| 狠狠综合久久| 亚洲国内欧美| 久久综合国产精品台湾中文娱乐网| 国产乱码精品一区二区三区卡| 成r视频免费观看在线播放| 欧美日韩伦理在线免费| 久久久999精品免费| 99热在线成人| 国产精品免费入口| 日韩avvvv在线播放| 欧美大黄免费观看| 亚洲国产精品成人天堂| 超碰精品在线观看| 欧美丰满一区二区免费视频| 欧美日韩高清在线一区| 四虎最新地址发布| 91九色精品| av一区二区三区免费观看| 日韩欧中文字幕| 国产一区二区不卡视频| 黄色片av在线| 免费欧美视频| 欧美日韩成人激情| 中文字幕无码精品亚洲资源网久久| 综合成人在线| 日韩精品久久久久久福利| 男同在线观看| 精品国产乱码久久久久久婷婷 | 国产在线精品一区免费香蕉 | 日韩电影中文字幕av| 正在播放国产精品| 亚洲成人黄色影院| 北条麻妃一区二区三区在线| av磁力番号网| 亚洲日本欧美中文幕| 麻豆国产精品777777在线| 麻豆av电影在线观看| 99精品99久久久久久宅男| 欧美色精品在线视频| 欧美三级小说| 96久久久久久| 亚洲精品中文字幕av| 高清在线一区| av成人午夜| 亚洲一本大道在线| 国内精品偷拍| 91九色综合久久| 99re视频精品| 中文字幕在线视频观看| 欧美视频一区在线观看| 欧美二区视频| 日韩中文字幕二区| 精品av久久707| 热久久天天拍国产| 欧美亚洲高清一区| 免费的黄网站在线观看| 欧美日韩国产中文| 一区二区中文字幕在线观看| 爱情岛论坛成人| 欧美在线不卡一区| 日韩伦理电影网站| 紧缚奴在线一区二区三区| 日本不卡一区在线| 欧美精品videofree1080p| 精品亚洲aⅴ乱码一区二区三区| 三级国产三级在线| 91sao在线观看国产| 亚洲精品成人a在线观看| 一区二区在线播放视频| 久久久久久久网| www.av中文字幕| 久久激情中文| 欧美激情喷水视频| 狠狠久久伊人| 蜜桃av色综合| 国产成人精品免费看| 亚洲精品中字| 成人av在线资源网| 91制片厂毛片| 欧美国产日韩亚洲一区| 九七影院理伦片| 欧美精品一区二区三区久久久| 亚洲精品a级片| 搞黄视频在线观看| 国产三区二区一区久久| 精品欧美乱码久久久久久1区2区| 国产九九视频一区二区三区| 精品久久久国产| 另类中文字幕国产精品| caoporn超碰国产公开| 日本一区视频在线观看| 国产亚洲精品久久久久久| 欧美国产乱子伦| 国内精品久久久久久久97牛牛| 成人美女大片| av黄色免费在线| 精品一区二区三区无码视频| 国模精品系列视频| 午夜精品一区二区三区三上悠亚| 国产综合色激情| 欧美三级在线观看视频| 亚洲第一av在线| av成人老司机| 精品国产不卡| 忘忧草在线日韩www影院| 亚洲欧美精品| 久久999免费视频| 亚洲制服丝袜av| 久久久久电影| h视频在线免费观看| 91精品一区二区| 色综合色狠狠天天综合色| 精品国产一区二区三区成人影院| 50路60路老熟妇啪啪| 伊人久久大香线蕉精品| 久久艹在线视频| 不卡区在线中文字幕| 日韩av影院| vam成人资源在线观看| 在线视频cao| 缴情综合网五月天| 风间由美一区二区三区| 欧美激情视频三区| 欧美xxxx在线观看| 久久久www成人免费毛片麻豆| 激情视频一区| 日本中文字幕电影在线观看 | 国产伦精品一区二区三区视频黑人 | 欧美日韩国产成人| 国产精品每日更新在线播放网址| 亚洲欧美综合国产精品一区| 欧美日韩夜夜| 制服丝袜日韩| 精品视频自拍| 久久一区二区三区喷水| 日韩欧美高清在线视频| 成全电影大全在线观看| 91影视免费在线观看| 欧美激情一区二区三区蜜桃视频 | 欧美亚洲国产一卡| 欧美日韩在线直播| 亚洲第一福利在线观看| 亚洲第一级黄色片| 中文字幕国产精品久久| 国产精品国产三级国产aⅴ浪潮 | 午夜精品一区二区三区在线| 亚洲电影第1页| 中文字幕亚洲综合久久菠萝蜜| 久久久久在线| 国产一区二区三区四区三区四| 欧美一区二区三区久久| 国产成人精品一区二区三区视频 | 色视频在线观看| 在线观看视频黄色| 亚洲精品日韩av| 88国产精品欧美一区二区三区| 国产婷婷成人久久av免费高清 | 成人性色生活片免费看爆迷你毛片| 日韩不卡在线观看日韩不卡视频| 免费不卡在线视频| 国产呦精品一区二区三区网站| 26uuu亚洲| 欧美日韩久久久久| 国产精品成人av性教育| 91精品久久久久久久久不口人 | 国产亚洲福利社区| 亚洲精品国产电影| 日韩三级视频中文字幕| 亚洲美女视频一区| 亚洲乱码国产乱码精品精的特点| 美女网站在线免费欧美精品| 精品午夜久久福利影院 | 羞羞视频网站在线观看| 午夜探花在线观看| 欧洲一区二区视频| 精品国产亚洲在线| 国产欧美日韩三区| www.色综合.com| 久久综合色8888| 91精品国产综合久久福利| 久久久精品影院| 亚洲精品高清国产一线久久| 免费a在线观看| 欧美男同视频网| 国产精品乱人伦中文| 欧美激情18p|