Go 記憶體管理與記憶體清理

2022-04-05 05:32:38 字數 2127 閱讀 7011

illustration created for 「a journey with go」, made from the original go gopher, created by renee french.

這篇文章基於 go 1.13 版本。有關記憶體管理的討論在我的文章 」go:記憶體管理與分配 」 中有解釋。

清理記憶體是乙個過程,它能夠讓 go 知道哪些記憶體段最近可用於分配。但是,它並不會使用將位置 0 的方式來清理記憶體。

將記憶體置 0 的過程 —— 就是把記憶體段中的所有位賦值為 0 —— 是在分配過程中即時執行的。

zeroing the memory

但是,我們可能想知道 go 採用什麼樣的策略去知道哪些物件能夠用於分配。由於在每個範圍內有乙個內部位圖allocbits,go 實際上會追蹤那些空閒的物件。讓我們從初始態開始來回顧一下它的工作流程,

free objects tracking with allocbits

就效能角度來看,allocbits代表了乙個初始態並且會保持不變,但是它會由freeindex(乙個指向第乙個空閒位置的增量計數器)所協助。

然後,第乙個分配就開始了:

free objects tracking with allocbits

freeindex現在增加了,並且基於allocbits知道了下一段空閒位置。

分配過程將會再一次出現,之後, gc 將會啟動去釋放不再被使用的記憶體。在標記期間,gc 會用乙個位圖gcmarkbits來跟蹤在使用中的記憶體。讓我們通過我們執行的程式以相同的示例為例,在第乙個塊不再被使用的地方。

memory tracking during the garbage collector

正在被使用的記憶體被標記為黑色,然而當前執行並不能夠到達的那些記憶體會保持為白色。

有關更多關於標記和著色階段的資訊,我建議你閱讀我的這篇文章 go:gc 是如何標記記憶體的? 現在,我們可以使用gomarkbits精確檢視可用於分配的記憶體。go 現在也使用gomarkbits代替了allocbits,這個操作就是記憶體清理:

sweeping a span

但是,這必須在每乙個範圍內執行完畢並且會花費許多時間。go 的目標是在清理記憶體時不阻礙執行,並為此提供了兩種策略。

go 提供了兩種方式來清理記憶體:

關於後台工作程式,當開始執行程式時,go 將設定乙個後台執行的 worker(唯一的任務就是去清理記憶體),它將進入睡眠狀態並等待記憶體段掃瞄:

background sweeper

通過追蹤過程的週期,我們也能看到這個後台工作程式總是出現去清理記憶體:

background sweeper

清理記憶體段的第二種方式是即時執行。但是,由於這些記憶體段已經被分發到每乙個處理器的本地快取mcache中,因此很難追蹤首先清理哪些記憶體。這就是為什麼 go 首先將所有記憶體段移動到mcentral的原因。

spans are released to the central list

然後,它將會讓本地快取mcache再次請求它們,去即時清理:

sweep span on the fly during allocation

即時掃瞄確保所有記憶體段在儲存資源的過程中都會得到清理,同時會儲存資源以及不會阻塞程式執行。

正如之前看到的,由於後台只有乙個 worker 在清理記憶體塊,清理過程可能會花費一些時間。但是,我們可能想知道如果另乙個 gc 週期在一次清理過程中啟動會發生什麼。在這種情況下,這個執行 gc 的 goroutine 就會在開始標記階段前去協助完成剩餘的清理工作。讓我們舉個例子看一下連續呼叫兩次 gc,包含數千個物件的記憶體分配的過程。

sweeping must be finished before a new cycle

但是,如果開發者沒有強制呼叫 gc,這個情況並不會發生。在後台執行的清理工作以及在執行過程中的清理工作應該足夠多,因為清理記憶體塊的數量和去觸發乙個新的週期(譯者注:gc 週期)的所需的分配的數量成正比。

本文由 gctt 原創編譯,go語言中文網 榮譽推出

記憶體分配 Go記憶體管理 記憶體分配一

go作為乙個比較新晚 新 的語言,自然借鑑前輩們的優點,比如說語言本身負責記憶體管理 對協程和高併發的高優支援 簡單高效的語法等。本篇及後續的幾篇要講的就是還沒提到的比較複雜的記憶體管理。學習記憶體管理 分配 前,如果有jvm的記憶體管理的基礎,會變得非常簡單,如果是第一次接觸記憶體管理,在看完go...

Linux記憶體清理

第一類單位引數 1 b,bytes,以byte為單位顯示記憶體使用情況 2 k,kilo,以kb為單位,這也是預設值 3 m,mega,以mb為單位顯示內容使用情況 4 g,giga,以gb為單位顯示記憶體使用情況 第二類引數 1 h,human,自動將數值轉換為人類易讀形式 2 c,count,展...

Linux 記憶體清理

1.clear pagecache only.sync echo 1 proc sys vm drop caches 2.clear dentries and inodes.sync echo 2 proc sys vm drop caches 3.clear pagecache,dentries ...