Go 1.3 垃圾收集器保留伺服器記憶體
理解問題
處理不規則流量連接的TCP 伺服器正在使用大量系統記憶體不會被釋放回作業系統。當在同一台機器上運行多個伺服器時,這種行為會出現問題,因為記憶體資源可能會隨著時間的推移而耗盡。
背景
Go 的垃圾收集器 (GC) 會釋放未使用的堆內存,但它不會釋放未使用的堆內存。不要總是縮小行程的虛擬位址空間。在 Windows 平台上,這是不可能的。即使在基於 Unix 的系統上,Go 也會使用系統呼叫來通知作業系統可以回收未使用的堆內存,但這需要時間(最多 7 分鐘)。
分析
基於從Go 社群論壇收集的資訊來看,該問題可能與以下因素有關:
-
Go 沒有釋放所有記憶體到作業系統: Go 只釋放堆疊變數; goroutine 堆疊不會被釋放。
-
延遲記憶體釋放: 內存在被 GC 標記為空閒後可能不會立即返回作業系統。還需要進行作業系統掃描,可能需要長達 7 分鐘的時間。
-
過度報告的記憶體使用情況:並非所有分配的記憶體都是「真實」記憶體。有些可能被運行時使用,但程式不會使用,讓作業系統來處理。
潛在的解決方案
-
明確記憶體釋放:強制垃圾使用runtime.GC()進行收集並使用明確釋放記憶體給操做系統runtime.FreeOSMemory.
限制
- 應謹慎使用runtime.GC(),因為它會影響效能。
- runtime.FreeOSMemory 只能工作如果 GC 已執行。
- Goroutine 堆疊記憶體將不會被佔用已發布。
致謝
- Dmitri Vyukov(Go 開發者)提供了有關該問題的重要見解。
以上是為什麼我的Go 1.3伺服器不將記憶體釋放回作業系統?的詳細內容。更多資訊請關注PHP中文網其他相關文章!