我的程序從操作系統(tǒng)獲取內(nèi)存但沒有返回。它讀取內(nèi)存中的文件,處理它們,然后等待下一個(gè)文件。一般來說,我有小文件,但有時(shí)我有大文件。當(dāng)我的程序處理大文件時(shí),它會(huì)向操作系統(tǒng)請求大量內(nèi)存,但不會(huì)將其返回。我找到了與 using 相關(guān)的問題/答案debug.FreeOSMemory(),但它不適用于我的代碼示例。我在真實(shí)系統(tǒng)中遇到了問題,但我可以在一個(gè)小例子中重現(xiàn)它:package mainimport ( "fmt" "math/rand" "runtime" "runtime/debug")type Data struct { a int b int c string}var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")func randSeq(n int) string { b := make([]rune, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b)}func stat(description string) { var rtm runtime.MemStats runtime.ReadMemStats(&rtm) fmt.Printf("%s -> Alloc: %d; Sys: %d\n", description, rtm.Alloc, rtm.Sys)}func mapAllocate() map[string]Data { var data = make(map[string]Data) for i := 0; i < 10000; i++ { key := randSeq(100) el := Data{ a: rand.Int(), b: rand.Int(), c: randSeq(rand.Intn(10000)), } data[key] = el } return data}func main() { stat("Start program") var result map[string]Data for i := 0; i < 10; i++ { result = mapAllocate() stat("Map allocate") result = make(map[string]Data) runtime.GC() debug.FreeOSMemory() stat("GC call ") } fmt.Println(len(result)) runtime.GC() debug.FreeOSMemory() for true { stat("Waiting ") time.Sleep(30 * time.Second) }}當(dāng)然,我在實(shí)際應(yīng)用中不會(huì)調(diào)用 GC。我在這里用它來演示我的問題。如果理解正確:程序從堆中分配內(nèi)存。Go 運(yùn)行時(shí)第一次沒有足夠的內(nèi)存并從操作系統(tǒng)請求它。我調(diào)用 GC,它從內(nèi)存中釋放對象。但是 Go 運(yùn)行時(shí)不會(huì)將此內(nèi)存返回給操作系統(tǒng)。這對我來說是個(gè)問題,因?yàn)槌绦颢@取了大文件,獲取了大量內(nèi)存,并且在 OOM 殺手殺死程序的一個(gè)實(shí)例之前(幾天)永遠(yuǎn)不會(huì)將其返回給操作系統(tǒng)。為什么 Go 運(yùn)行時(shí)不會(huì)將此內(nèi)存返回給操作系統(tǒng),我該如何解決?
如何將內(nèi)存返回給操作系統(tǒng)
慕工程0101907
2022-06-06 15:24:44