成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Slice 擴容后容量及內存如何計算?

開發 后端
只有了解了 Go 的內存分配規律,我們才能準確的計算出我們最少得買多少的綠豆糕(得申請多少的內存,分配多少的容量)。

[[429043]]

1. 擴容后預估容量

假設現在有一個長度為 2 的切片,對其進行擴容,增加三個元素

  1. sli := []int{1,2} 
  2. sli = append(sli, 3, 4, 5) 

對于擴容后的切片,長度為 5,這一點沒有任何爭議。

但容量呢?難道也是 5?

經過運行驗證,實際的容量為 6 。

什么情況?這 6 是如何計算出來的呢?

這就不得不去 Go 源代碼中一探究竟,在 runtime/slice.go 關于 slice 擴容增長的代碼如下:

  1. newcap := old.cap 
  2. if newcap+newcap < cap { 
  3.     newcap = cap 
  4. else { 
  5.     for { 
  6.         if old.len < 1024 { 
  7.             newcap += newcap 
  8.         } else { 
  9.             newcap += newcap / 4 
  10.         } 
  11.         if newcap >= cap { 
  12.             break 
  13.         } 
  14.     } 

對于這段代碼,只要理解前兩行,其他的就不攻自破了

  • 第一行的 old.cap:擴容前的容量,對于此例,就是 2
  • 第二行的 cap:擴容前容量加上擴容的元素數量,對于此例,就是 2+3

整段代碼的核心就是要計算出擴容后的預估容量,也就是 newcap,計算的具體邏輯是:

  1. 若 old.cap * 2 小于 cap,那 newcap 就取大的 cap
  2. 若 old.cap * 2 大于 cap,并且old.cap 小于 1024,那 newcap 還是取大,也即 newcap = old.cap * 2
  3. 若 old.cap * 2 大于 cap,但是old.cap 大于 1024,那兩倍冗余可能就有點大了,系數換成 1.25,也即 newcap = old.cap * 2

但 newcap 只是預估容量,并不是最終的容量,要計算最終的容量,還需要參考另一個維度,也就是內存分配。

 2. 內存的分配規律

舉個現實中的例子來說

你家里有五個人,每個人都想吃綠豆糕,因此你的需求就是 5,對應上例中的 cap ,于是你就到超市里去買。

但超市并不是你家開的,綠豆糕都是整盒整盒的賣,沒有賣散的,每盒的數量是 6 個,因此你最少買 6 個。

每次購買的最少數量,就可以類比做 Go 的內存分配規律。

只有了解了 Go 的內存分配規律,我們才能準確的計算出我們最少得買多少的綠豆糕(得申請多少的內存,分配多少的容量)。

關于內存管理模塊的代碼,在 runtime/sizeclasses.go

  1. // class  bytes/obj  bytes/span  objects  tail waste  max waste 
  2. //     1          8        8192     1024           0     87.50% 
  3. //     2         16        8192      512           0     43.75% 
  4. //     3         32        8192      256           0     46.88% 
  5. //     4         48        8192      170          32     31.52% 
  6. ... 
  7. //    17        256        8192       32           0      5.86% 
  8. //    18        288        8192       28         128     12.16% 
  9. //    19        320        8192       25         192     11.80% 
  10. //    20        352        8192       23          96      9.88% 
  11. //    21        384        8192       21         128      9.51% 
  12. //    22        416        8192       19         288     10.71% 
  13. //    23        448        8192       18         128      8.37% 
  14. //    24        480        8192       17          32      6.82% 
  15. //    25        512        8192       16           0      6.05% 
  16. ... 
  17. //    66      32768       32768        1           0     12.50% 

從上面這個表格中,可以總結出一些規律。

  • 在小于16字節時,每次以8個字節增加
  • 當大于16小于2^8時,每次以16字節增加
  • 當大于2^8小于2^9時以32字節增加
  • 依此規律…

3. 匹配到合適的內存

第一節中我們例子中,主人公是一個元素類型為 int 的切片,每個 int 占用為 8 個字節,由于我們計算出的 newcap 為 5,因此新的切片,最少最少要占用 5*8 = 40 個字節。

再到第二節中的表格中查看,發現離 40 byte 最接近的是 32 和 48 兩個檔位。

如果是 32 byte,就是不夠用了,

因此 只能選擇 48 這個檔位去分配內存。

有了實際分配的內存,再反回去計算容量,就是擴容后真實的切片容量,也就是 48/8 = 6

 

是不是很簡單呢?

 

責任編輯:武曉燕 來源: Go編程時光
相關推薦

2023-11-28 11:44:54

Go切片

2010-06-02 11:33:26

Linux 內存監控

2021-01-18 05:15:30

存儲容量服務器

2021-08-16 06:56:21

Slice數組類型內存

2023-03-13 13:36:00

Go擴容切片

2018-11-06 10:08:34

無線AP網絡帶寬無線網絡

2021-01-04 10:54:58

云計算容量管理

2021-08-12 14:19:14

Slice數組類型內存

2017-12-11 11:00:27

內存泄露判斷

2012-08-14 10:05:08

2022-02-15 08:55:16

參數Go函數

2017-08-28 15:32:52

內存DDR4DDR3

2014-03-14 13:32:52

cgroupsLinux容器

2009-02-16 18:08:01

linux硬件信息cpu

2010-06-04 15:30:44

Linux 查看內存

2009-12-08 13:40:58

Windows XP系

2010-08-04 10:10:03

光纖網絡容量爆炸

2025-06-04 02:15:55

Go語言Slice

2009-07-28 19:08:59

云計算存儲刀片服務器

2023-03-31 07:31:28

SliceGolang
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 狠狠操狠狠操 | 欧美一区二区三区在线看 | 国产一区不卡 | 亚洲福利一区二区 | 欧美成人免费在线 | 男人天堂99 | www.久久 | 精品国产乱码一区二区三区 | 一区二区三区国产 | 国产综合久久 | 女朋友的闺蜜3韩国三级 | 成人av鲁丝片一区二区小说 | 精品国产18久久久久久二百 | 欧美韩一区二区 | 中文字字幕一区二区三区四区五区 | 欧美精品久久 | 日韩欧美日韩在线 | 欧美视频 亚洲视频 | 99精品在线 | 国产视频观看 | av一级毛片| 国产精品乱码一区二区三区 | 亚洲va欧美va天堂v国产综合 | 国产第一亚洲 | 日韩三级一区 | 成人在线观 | 91视频一区 | 国产91 在线播放 | 亚洲最新网址 | 97视频免费 | 超碰97免费在线 | av一级在线观看 | 亚洲一区二区三区免费视频 | 久久网一区二区 | 精品国产区 | 亚洲人成人一区二区在线观看 | 日本免费一区二区三区四区 | 国产午夜视频 | 福利视频一区二区 | 91精品国产色综合久久 | 欧美1区2区|