2015-07-22 46 views
4

當我創建一個新的切片或結構用一個品牌或新的呼叫:Go如何在make或new calls中分配內存?

s := make([]int64, 10, 100) 
o := new(MyStruct) 

多少內存去同一個內存分配系統調用分配?是否預先分配內存,以便後續調用不會觸發新的系統調用?

我在問這個,因爲我需要經常在我的代碼中分配內存。我不確定是否需要自己實現內存分配器,或者如果我可以依靠Go來執行骯髒的工作。如果Go預分配內存,我可以自定義分配的塊大小嗎?

我寫圍棋一些實驗代碼,並運行在strace的代碼,但我不明白圍棋確實與mmap系統調用:

mmap(0xc000000000, 65536, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000 
munmap(0xc000000000, 65536)    = 0 
mmap(NULL, 262144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1017000 
mmap(0xc208000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc208000000 
mmap(0xc207ff0000, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc207ff0000 
mmap(0xc000000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xc000000000 
mmap(NULL, 65536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd1007000 
mmap(NULL, 1439992, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efdd0ea7000 
+2

你可以依靠去做骯髒的工作。它呼籲系統獲取更多的東西,而不僅僅是爲小的「make」/「new」調用分配的內容。如果你想了解詳情,https://github.com/golang/go/blob/master/src/runtime/mem_linux.go可能是一個起點。但通常情況下,我認爲你想要擴大你的產品,然後讓簡介告訴你什麼是緩慢的。 – twotwotwo

+0

快速提問:是否在保留內存中分配不同大小的插槽以避免碎片?也許我需要閱讀的源代碼... – NeoWang

+4

https://github.com/golang/go/blob/master/src/runtime/malloc.go – kostya

回答

2

你可能會從「過早優化」綜合症患這裏。語言規範說沒有任何內容關於如何分配由make()分配的內存。

例如,圍棋的符合標準的實現可能會執行該做make([]foo, ...)功能的徹底analyzis和證明:

  1. 返回不逃避功能的範圍切片值。
  2. append()不在此切片值上調用。
  3. 切片值不傳遞給任何調用的函數。

在這種情況下,切片的後備存儲可能被分配到堆棧上。

當然,我是在重新集聚,但是它的語義沒有在語言規範中聲明。目前有兩個成熟的Go實現(其中一個來自谷歌,被稱爲gcgccgo),將來會有更多(llvmgo看起來有很好的機會),並且它們都有它們的特性。

所以請考慮閱讀pprof和一般的Go分析,並做簡介樣本(但真實)的代碼。

搜索the mailing list單詞「profile」,「profiling」,「堆和配置文件」,「CPU和配置文件」和「pprof」將爲您提供很多洞察。

也考慮thisthis

+0

僅供參考我想實現一個緩存服務器,所以內存管理不過早優化。 – NeoWang

+1

@NeoWang,那麼你可能會對['sync.Pool'](http://www.reddit。com/r/golang/comments/2ap67l/when_to_use_syncpool_and_when_not_to /)或[外部內存池](http://blog.golang.org/qihoo)或[內部內存池](https://blog.cloudflare.com/recycling - 內存緩衝器功能於去/)。 – kostix

+1

@NewWang,總的來說,我強烈建議你在郵件列表上提問,明確提及你的任務並徵求意見。實際上,這樣的研究是錯誤的媒介。 – kostix