精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go 官方詳解“Green Tea”垃圾回收器:從對象到頁,一場應對現代硬件挑戰的架構演進

開發 前端
Go 1.25?包含一個名為“綠茶”(Green Tea)的全新實驗性垃圾回收器,在構建時通過設置?GOEXPERIMENT=greenteagc?即可啟用。使用該垃圾回收器后,許多工作負載在垃圾回收上花費的時間減少了約 10%,而有些工作負載的降幅甚至高達 40%!

為了幫助大家深入理解這一重大變更背后的技術原理與深層思考,我翻譯了 Go 官方博客10月29日的最新文章《The Green Tea Garbage Collector》。該文是基于 Go 團隊核心成員 Michael Knyszek 在 GopherCon 2025 大會上的演講整理而成。在這篇極具技術深度的原理文章中,沒有人能比官方團隊的講解更為專業和權威。因此,為了最大程度地保留其“原汁原味”,我選擇以全文翻譯的形式,將其最真實、最精確的面貌呈現給大家。

以下是譯文全文,供大家參考。

Go 1.25 包含一個名為“綠茶”(Green Tea)的全新實驗性垃圾回收器,在構建時通過設置 GOEXPERIMENT=greenteagc 即可啟用。使用該垃圾回收器后,許多工作負載在垃圾回收上花費的時間減少了約 10%,而有些工作負載的降幅甚至高達 40%!

它已為生產環境準備就緒,并在 Google 內部投入使用,因此我們鼓勵你進行嘗試。我們知道某些工作負載的收益不大,甚至完全沒有,所以你的反饋對于我們向前推進至關重要。根據我們目前掌握的數據,我們計劃在 Go 1.26 中將其設為默認GC。

如需報告任何問題,請提交一個新 issue。

如需分享任何成功經驗,請回復至現有的 Green Tea issue。

下文是基于 Michael Knyszek 在 GopherCon 2025 上的演講整理的博文。一旦演講視頻上線,我們將會更新此博文并附上鏈接。

追蹤垃圾回收過程

在討論“綠茶”之前,讓我們先就垃圾收集問題達成共識。

對象和指針

垃圾回收的目的是自動回收并重用程序不再使用的內存。

為此,Go 垃圾回收器關注的是對象(Object)和指針(Pointer)。

在 Go 運行時的上下文中,對象是Go值(Value),其底層內存分配自堆。當 Go 編譯器無法找到其他方式為某個值分配內存時,就會創建堆對象。例如,以下代碼片段會分配一個堆對象:一個指針切片的底層存儲空間。

var x = make([]*int, 10) // 全局變量

Go 編譯器只能在堆上分配切片后備存儲,因為它很難(甚至可能不可能)知道 x 將引用該對象多長時間。

指針只是一些數字,用于指示 Go 值在內存中的位置,Go 程序通過它們來引用對象。例如,要獲取上一個代碼片段中分配的對象的起始指針,我們可以這樣寫:

&x[0] // 0xc000104000

標記-清除算法

Go 的垃圾回收器遵循一種廣義上稱為“追蹤式垃圾回收”的策略,這意味著垃圾回收器會跟隨或追蹤程序中的指針,以識別程序仍在使用的對象。

更具體地說,Go 垃圾回收器實現了標記-清除(mark-sweep)算法。這比聽起來要簡單得多。 可以把對象和指針想象成計算機科學意義上的圖:對象是節點,指針是邊。

標記-清除算法就在這個圖上運行的,顧名思義,它分兩個階段進行。

在第一階段,即標記階段,它從一組明確定義的、稱為“根(root)”的源邊開始遍歷對象圖。可以將其理解為全局變量和局部變量。然后,它將沿途找到的所有東西標記為已訪問(visited),以避免循環。這類似于典型的圖遍歷算法,如深度優先或廣度優先搜索。

接下來是清除階段。在我們的圖遍歷中未被訪問到的任何對象,都是程序未使用或不可達(unreachable)的。我們稱這種狀態為不可達,因為通過語言的語義,正常的安全 Go 代碼已無法再訪問那塊內存。為完成清除階段,算法只需遍歷所有未訪問的節點,并將其內存標記為空閑,以便內存分配器可以重用它們。

就是這樣?

你可能覺得我在這里把事情想得有點過于簡單了。垃圾回收器經常被比作魔法和黑盒子 。你的說法也對了一部分,實際情況要復雜得多。

例如,實際上,這個算法會與你的常規 Go 代碼并行執行。遍歷一個不斷變化的圖會帶來挑戰。我們還對這個算法進行了并行化,這一點稍后會再次提及。

但請相信我,這些細節大多與核心算法無關。核心算法實際上只是一個簡單的圖泛洪(graph flood)操作。

圖泛洪示例

我們來看一個例子。請瀏覽下面的幻燈片圖片,跟隨步驟操作。

圖片圖片

這里我們有一個包含一些全局變量和 Go 堆的圖示。讓我們一步步來分析。

圖片圖片

左邊是我們的根。它們是全局變量 x 和 y。這將是我們圖遍歷的起點。根據左下角的圖例,它們被標記為藍色,表示它們當前在我們的工作列表上。

圖片圖片

右邊是我們的堆。目前,堆中的所有東西都是灰色的,因為我們還沒有訪問過任何部分。

圖片圖片

每個矩形中代表一個對象。每個對象都標有其類型。這個特殊的對象是 T 類型的對象,其類型定義在左上角。它有一個指向子節點數組的指針和一些值。我們可以推斷這是一種遞歸的樹形數據結構。

圖片圖片

除了 T 類型的對象,你還會注意到我們有包含 *T 的數組對象。這些數組對象由 T 類型對象的 "children" 字段指向。

圖片圖片

矩形內的每個方塊代表 8 字節的內存。帶有點的方塊是一個指針。如果它有箭頭,那么它是一個指向某個其他對象的非空指針。

圖片圖片

如果它沒有對應的箭頭,那么它就是一個空指針。

圖片圖片

接下來,這些虛線矩形代表空閑空間,我稱之為空閑“槽位(slot)”。我們可以在那里放置一個對象,但目前還沒有。

圖片圖片

你還會注意到對象被這些帶標簽的、虛線圓角矩形組合在一起。每一個都代表一個頁(page):一塊連續的內存塊。這些頁被標記為 A、B、C 和 D,我將以此來稱呼它們。

在這個圖中,每個對象都被分配到某個頁面中。就像實際實現一樣,這里的每個頁面只包含特定大小的對象。這正是 Go 堆的組織方式。

圖片圖片

頁也是我們組織每個對象元數據的方式。這里你可以看到七個框,每個對應頁 A 中的七個對象槽位之一。

每個框代表一位(bit)信息:我們之前是否見過這個對象。實際上,Go運行時就是通過這種方式來管理對象是否已被訪問過的,這一點稍后會很重要。

圖片圖片

細節講了很多,感謝你跟讀。這些稍后都會派上用場。現在,讓我們看看圖泛洪如何應用于這幅圖。

圖片圖片

我們首先從工作列表中取出一個根。我們將其標記為紅色,表示它現在是活躍的。

圖片圖片

沿著根指針,我們找到了一個 T 類型的對象,并將其添加到我們的工作列表。根據圖例,我們將該對象繪制成藍色,以表明它已在工作列表中。請注意,我們同時在右上角的元數據中設置了與此對象對應的“已見”位。

圖片圖片

下一個根也同樣處理。

圖片圖片

現在我們處理完了所有的根,工作列表上還剩下兩個對象。讓我們從工作列表中取出一個對象。

圖片圖片

我們現在要做的是遍歷該對象的指針,以找到更多的對象。順便說一下,我們稱遍歷一個對象的指針為“掃描”該對象。

圖片圖片

我們找到了這個有效的數組對象…

圖片圖片

… 并將其添加到我們的工作列表中。

圖片圖片

從這里開始,我們遞歸地進行。

圖片圖片

我們遍歷數組的指針。

圖片圖片

圖片圖片

圖片圖片

找到更多對象…

圖片圖片

圖片圖片

圖片圖片

然后我們遍歷數組對象引用的那些對象!

圖片圖片

請注意,我們仍然需要遍歷所有指針,即使它們是 nil。我們事先并不知道它們是否為空。

圖片圖片

這個分支下還有一個對象…

圖片圖片

圖片圖片

現在我們到達了另一個分支,從我們早先從某個根找到的頁 A 中的那個對象開始。

你可能注意到了我們工作列表的“后進先出”規則,這表明我們的工作列表是一個棧,因此我們的圖遍歷近似于深度優先。這是有意為之的,并反映了 Go 運行時中實際的圖遍歷算法。

圖片圖片

讓我們繼續…

圖片圖片

接下來我們找到了另一個數組對象…

圖片圖片

并遍歷它…

圖片圖片

圖片圖片

圖片圖片

圖片圖片

圖片圖片

我們的工作列表上只剩最后一個對象了…

圖片圖片

讓我們掃描它…

圖片圖片

圖片圖片

標記階段完成了!我們沒有任何正在處理的工作,工作列表也空了。所有用黑色繪制的對象都是可達的,所有用灰色繪制的對象都是不可達的。讓我們一次性清除所有不可達的對象。

圖片圖片

我們已將那些對象轉換為空閑槽位,準備好容納新的對象。

問題所在

經過上面一番摸索,我認為我們已經掌握了 Go 垃圾回收器的實際工作原理。目前看來,這個過程運行良好,那么問題出在哪里呢?

事實證明,在某些程序中,執行這個特定算法會花費大量時間,而且幾乎會給所有 Go 程序帶來顯著的開銷。Go 程序將 20% 甚至更多的 CPU 時間用于垃圾回收的情況并不少見。

讓我們來分析一下這些時間都花在了哪里。

垃圾回收成本

在宏觀層面上,垃圾回收器的成本由兩部分組成。一是運行頻率,二是每次運行所做的工作量。將這兩者相乘,就得到了垃圾回收的總成本。

Total GC cost = Number of GC cycles × Average cost per GC cycle

即 總 GC 成本 = GC 周期數 × 每個 GC 周期的平均成本

多年來,我們一直在研究這個等式中的這兩個術語。要了解更多關于垃圾回收器運行頻率的信息,請參閱 Michael 在 2022 年 GopherCon EU 大會上的關于內存限制的演講。 Go 垃圾回收器的指南也對此主題進行了很多闡述,如果你想深入了解,值得一看。

但現在,我們只關注第二部分,即每個周期的成本。

多年來,我們不斷研究 CPU Profile分析結果,試圖提高性能,從中我們了解到 Go 的垃圾回收器有兩大特點。

第一,大約 90% 的垃圾回收器成本都花在了標記上,只有大約 10% 是在清除。事實證明,清除比標記更容易優化,多年來 Go 已經擁有了一個非常高效的清除器。

第二,在那段用于標記的時間里,有相當大一部分(通常至少有 35%),都浪費在了訪問堆內存上。這本身已經夠糟糕了,更糟糕的是,它完全阻礙了現代 CPU 真正高速運行的關鍵機制。

“微架構災難”

在這種情況下,“堵塞工作機制(gump up the works)”意味著什么?現代 CPU 的具體構造相當復雜,所以我們用一個類比來說明。

想象 CPU 在一條路上行駛,這條路就是你的程序。CPU 想要加速到很高的速度,為此它需要能看清前方的路,并且道路必須暢通。但圖遍歷算法對 CPU 來說,就像在城市街道里開車。CPU 看不到拐角后的情況,也無法預測接下來會發生什么。為了前進,它必須不斷地減速、轉彎、在紅綠燈前停下、避開行人。你的引擎有多快幾乎無關緊要,因為你根本沒有機會真正跑起來。

讓我們通過再次審視我們的例子來使這一點更具體。我在這里的堆上疊加了我們所走的路徑。每個從左到右的箭頭代表我們做的一段掃描工作,虛線箭頭則顯示了我們在不同掃描工作之間是如何跳轉的。

圖片圖片

上圖展示了我們的圖泛洪示例中,垃圾回收器在堆中執行的路徑。

請注意,我們正在內存中到處跳轉,在每個地方只做一點點工作。特別是,我們頻繁地在頁之間,以及頁的不同部分之間跳轉。

現代 CPU 做了大量的緩存。訪問主內存可能比訪問緩存中的內存慢上 100 倍。CPU 緩存中填充的是最近訪問過的內存,以及與最近訪問過的內存相鄰的內存。但是,并不能保證兩個相互指向的對象在內存中也彼此靠近。圖泛洪算法并沒有考慮到這一點。

補充一點:如果我們只是在等待從主內存中獲取數據,情況可能還沒那么糟。CPU 會異步地發出內存請求,所以即使是慢的請求也可以重疊,只要 CPU 能看得足夠遠。但在圖遍歷中,每一小段工作都是不可預測的,并且高度依賴于上一段工作,所以 CPU 被迫幾乎在每一次獨立的內存獲取后都進行等待。

不幸的是,對我們來說,這個問題只會越來越嚴重。業界有句格言:“等兩年,你的代碼會變得更快。”

但 Go,作為一個依賴于標記-清除算法的垃圾回收語言,卻面臨著相反的風險。“等兩年,你的代碼會變得更慢。” 現代 CPU 硬件的趨勢正在給垃圾回收器的性能帶來新的挑戰:

  • 非一致性內存訪問 (Non-uniform memory access)。 首先,內存現在往往與 CPU 核心的子集相關聯。其他 CPU 核心訪問該內存的速度比前者慢。換句話說,主內存訪問的成本取決于哪個 CPU 核心正在訪問它。這種成本是不一致的,因此我們稱之為非一致內存訪問,簡稱 NUMA。
  • 內存帶寬減少 (Reduced memory bandwidth)。 每個 CPU 的可用內存帶寬隨著時間推移呈下降趨勢。這意味著雖然我們擁有更多的 CPU 核心,但每個核心能夠提交的數據量相對較少。 對主內存的請求導致未緩存的請求等待時間比以前更長。
  • 越來越多的 CPU 核心 (Ever more CPU cores)。 上面,我們看的是一個順序的標記算法,但真正的垃圾回收器是并行執行此算法的。這在核心數量有限的情況下擴展得很好,但即使經過精心設計,用于掃描的共享對象隊列也會成為一個瓶頸。
  • 現代硬件特性 (Modern hardware features)。 新硬件擁有像向量指令這樣的酷炫功能,讓我們能一次性操作大量數據。雖然這有可能大幅提升速度,但目前還不清楚如何才能實現這一點。因為標記工作包含很多不規則且通常是小塊的工作。

綠茶(Green Tea)

最后,我們來看看綠茶算法,這是我們對標記掃描算法的一個新的嘗試。綠茶算法的核心思想非常簡單:

操作頁面,而不是對象。

聽起來很簡單,對吧?然而,為了弄清楚如何安排對象圖遍歷的順序以及我們需要跟蹤哪些內容才能使其在實踐中有效運作,我們做了大量的工作。

更具體地說,這意味著:

  • 我們不再掃描對象,而是掃描整個頁。
  • 我們不再在工作列表上跟蹤對象,而是跟蹤整個頁。
  • 我們最終(在一個掃描周期結束時)仍然需要標記對象,但我們會跟蹤每個頁面本地標記的對象,而不是跟蹤整個堆中的標記對象。

綠茶示例

讓我們通過再次審視我們的示例堆,來看看這在實踐中意味著什么,但這次運行的是“綠茶”而不是直接的圖泛洪。

和之前一樣,請跟隨帶注釋的幻燈片進行瀏覽。

圖片圖片

這和之前的堆是一樣的,但現在每個對象有兩個比特的元數據而不是一個。同樣,每個比特或框,對應于頁中的一個對象槽位。總的來說,我們現在有 14 個比特對應于頁 A 中的七個槽位。

頂部的比特代表和以前一樣的東西:我們是否見過一個指向該對象的指針。我稱之為“已見” (seen) 位。底部的比特集是新的。這些“已掃描” (scanned) 位跟蹤我們是否已經掃描了該對象。

這塊新的元數據是必需的,因為在“綠茶”中,工作列表跟蹤的是頁,而不是對象。我們仍然需要在某種程度上跟蹤對象,這就是這些比特的目的。

圖片圖片

我們和以前一樣開始,從根開始遍歷對象。

圖片圖片

圖片圖片

但這一次,我們不是把一個對象放到工作列表上,而是把整個頁——在這里是頁 A——放到工作列表上,通過將整個頁用藍色陰影表示。

圖片圖片

我們找到的對象也是藍色的,表示當我們從工作列表中取出這個頁時,我們將需要查看那個對象。請注意,對象的藍色調直接反映了頁 A 中的元數據。其對應的“已見”位被設置,但其“已掃描”位沒有。

圖片圖片

我們跟隨下一個根,找到另一個對象,再次將整個頁——頁 C——放到工作列表上,并設置該對象的“已見”位。

圖片圖片

我們處理完根了,所以我們轉向工作列表,并從工作列表中取出頁 A。

圖片圖片

通過“已見”和“已掃描”位,我們可以知道頁 A 上有一個對象需要掃描。

圖片圖片

我們掃描那個對象,跟隨它的指針。結果,我們將頁 B 添加到工作列表,因為頁 A 中的第一個對象指向了頁 B 中的一個對象。

圖片圖片

我們處理完頁 A 了。接下來我們從工作列表中取出頁 C。

圖片圖片

與頁 A 類似,頁 C 上有一個單獨的對象需要掃描。

圖片圖片

我們在頁 B 中找到了一個指向另一個對象的指針。頁 B 已經在工作列表上了,所以我們不需要向工作列表添加任何東西。我們只需為目標對象設置“已見”位。

圖片圖片

現在輪到頁 B 了。我們在頁 B 上累積了兩個待掃描的對象,我們可以按內存順序,連續處理這兩個對象!

圖片圖片

我們遍歷第一個對象的指針…

圖片圖片

圖片圖片

圖片圖片

我們在頁 A 中找到了一個指向一個對象的指針。頁 A 之前在工作列表上,但此時不在了,所以我們把它放回工作列表。與原始的標記-清除算法不同,在原始算法中,任何給定的對象在整個標記階段最多只會被添加到工作列表一次;而在“綠茶”中,一個給定的頁在標記階段可能會多次出現在工作列表上。

圖片圖片

圖片圖片

我們在掃描完第一個之后,立即掃描頁中的第二個“已見”對象。

圖片圖片

圖片圖片

圖片圖片

我們在頁 A 中又找到了幾個對象…

圖片圖片

圖片圖片

圖片圖片

圖片圖片

我們掃描完頁 B 了,所以我們從工作列表中取出頁 A。

圖片圖片

這次我們只需要掃描三個對象,而不是四個,因為我們已經掃描過第一個對象了。我們通過查看“已見”和“已掃描”位之間的差異,來知道要掃描哪些對象。

圖片圖片

我們將按順序掃描這些對象。

圖片圖片

圖片圖片

圖片圖片

圖片圖片

圖片圖片

圖片圖片

我們完成了!工作列表上沒有更多的頁了,我們也沒有正在處理的東西。請注意,現在元數據都很好地對齊了,因為所有可達的對象都既被“已見”又被“已掃描”。

你可能在我們的遍歷過程中也注意到了,工作列表的順序與圖遍歷有點不同。圖遍歷是“后進先出”或類似棧的順序,而這里我們對工作列表上的頁使用的是“先進先出”或類似隊列的順序。

這是有意為之的。當頁在隊列中等待時,我們讓“已見”對象在每個頁上累積,這樣我們就可以一次性處理盡可能多的對象。這就是我們能一次性處理頁 A 上那么多對象的原因。有時候,懶惰是一種美德。

圖片圖片

最后,我們可以像以前一樣,清除掉未訪問的對象。

駛上高速公路

讓我們回到我們開車的比喻。我們終于要上高速公路了嗎?

讓我們回顧一下之前的圖泛洪圖片。

圖片圖片

原始圖遍歷在堆中穿行的路徑需要 7 次獨立的掃描。

我們到處跳躍,在不同的地方做著零碎的工作。“綠茶”所走的路徑看起來非常不同。

圖片圖片

“綠茶”所走的路徑僅需要 4 次掃描。

相比之下,綠茶在 A 和 B 頁面上從左到右的移動次數較少,但每次移動時間更長。 這些箭頭越長越好,箭頭堆積越多,這種效果就越強。這就是綠茶的魅力所在。

這也是我們馳騁高速公路的機會。

這一切都使得它與微架構更加契合。現在,我們可以更精確地掃描彼此靠近的對象,從而更有可能利用緩存并避免使用主內存。同樣,每頁的元數據也更有可能被緩存。跟蹤頁面而非對象意味著工作列表更小,而工作列表壓力的降低意味著爭用更少,CPU 停頓也更少。

說到高速公路,我們可以把我們比喻意義上的引擎開到以前從未開過的檔位,因為現在我們可以使用向量硬件了!

向量加速

如果你對向量硬件只有粗淺的了解,可能會不明白我們在這里如何使用它。但除了常見的算術和三角運算之外,最新的向量硬件還支持兩項對綠茶算法非常有用的功能:超寬寄存器和復雜的位運算。

大多數現代 x86 CPU 都支持 AVX-512 指令集,它擁有 512 位寬的向量寄存器。如此寬的寄存器足以在 CPU 上僅使用兩個寄存器來存儲整個頁面的所有元數據,從而使 Green Tea 能夠僅用幾條直線指令就完成整個頁面的掃描。向量硬件長期以來一直支持對整個向量寄存器進行基本的位運算,但從 AMD Zen 4 和 Intel Ice Lake 開始,它還支持一種新的位向量“瑞士軍刀”指令,使得 Green Tea 掃描過程中的關鍵步驟能夠在幾個 CPU 周期內完成。這些改進共同作用,使我們能夠大幅提升 Green Tea 的掃描循環速度。

對于之前的圖泛洪來說,這根本不可能,因為我們需要在各種大小的對象之間來回掃描。有時只需要兩條元數據,有時卻需要一萬條。向量硬件根本無法滿足這種可預測性和規律性要求。

如果你想深入了解一些細節,請繼續閱讀!否則,請隨時跳到下面的【評估】小節。

AVX-512 掃描內核

要了解 AVX-512 GC 掃描是什么樣子,請看下面的圖。

用于掃描的 AVX-512 矢量內核用于掃描的 AVX-512 矢量內核

這里面涉及的內容很多,我們可能光是解釋它的運作原理就能寫一整篇博客文章。現在,我們先從宏觀層面來概括一下:

  1. 首先,我們獲取頁面的“已查看”和“已掃描”位。請記住,頁面中的每個對象對應一位,并且頁面中的所有對象大小相同。
  2. 接下來,我們比較這兩個位集。它們的并集成為新的“掃描”位,而它們的差集則是“活動對象”位圖,它告訴我們在本次頁面掃描過程中(與之前的掃描相比)需要掃描哪些對象。
  3. 我們計算兩個位圖的差值并進行“擴展”,這樣就不是每個對象占用一位,而是頁面中的每個字(8 字節)占用一位。我們稱之為“活動字”位圖。例如,如果頁面存儲 6 個字(48 字節)的對象,則活動對象位圖中的每位將被復制到活動字位圖中的 6 位。如下所示:
0 0 1 1 ...  → 000000 000000 111111 111111 ...
  1. 接下來,我們獲取頁面的指針/標量位圖。同樣,這里的每一位都對應頁面的一個字(8 字節),并告訴我們該字是否存儲指針。這些數據由內存分配器管理。
  2. 現在,我們取指針/標量位圖和活動字位圖的交集。結果就是“活動指針位圖”:該位圖告訴我們尚未掃描的任何活動對象中包含的整個頁面中每個指針的位置。
  3. 最后,我們可以遍歷頁面內存并收集所有指針。邏輯上,我們遍歷活動指針位圖中的每個置位,加載該字處的指針值,并將其寫回緩沖區。該緩沖區稍后將用于標記已訪問的對象并將頁面添加到工作列表中。利用向量指令,我們只需幾條指令即可一次處理 64 字節。

讓這一切變快的部分原因是 VGF2P8AFFINEQB 指令,它是“Galios Field新指令” x86 擴展的一部分,也是我們上面提到的位操作“瑞士軍刀”。它是真正的明星,因為它讓我們能夠非常高效地完成掃描內核中的第 (3) 步。它執行逐位的仿射變換,將向量中的每個字節本身視為一個 8 位的數學向量,并將其與一個 8x8 的比特矩陣相乘。這一切都是在Galios Field GF(2) 上完成的,這意味著乘法是AND,加法是XOR。這樣做的好處是,我們可以為每個對象大小定義幾個 8x8 的比特矩陣,來精確地執行我們需要的 1:n 比特擴展。

完整的匯編代碼,請看這個文件。“擴展器”為每個大小類別使用不同的矩陣和不同的排列,所以它們在一個由代碼生成器編寫的單獨文件中。除了擴展函數,代碼量其實不多。大部分代碼都被極大地簡化了,因為我們可以在純粹位于寄存器中的數據上執行大部分上述操作。而且,希望很快這段匯編代碼將被 Go 代碼所取代!

感謝 Austin Clements 設計了這個過程。它非常酷,而且非常快!

評估

那么,這就是Green Tea的工作原理。它到底有多大幫助呢?

效果可能相當顯著。即使不考慮向量增強,我們的基準測試套件也顯示垃圾回收的 CPU 成本降低了 10% 到 40%。例如,如果應用程序 10% 的時間都花在了垃圾回收器上,那么根據工作負載的具體情況,整體 CPU 消耗將降低 1% 到 4%。垃圾回收 CPU 時間降低 10% 大致是典型的改進幅度。 (有關這些細節,請參閱 GitHub issue。)

我們在谷歌內部推廣了綠茶,并且大規模推廣后也看到了類似的效果。

我們仍在推出向量增強功能,但基準測試和早期結果表明,這將額外帶來 10%的 GC CPU 降低。

雖然大多數工作負載都能在一定程度上受益,但也有一些工作負載不會受益。

Green Tea 算法基于這樣的假設:我們可以一次性在單頁上累積足夠多的對象進行掃描,從而抵消累積過程的成本。如果堆結構非常規則(對象大小相同,且在對象圖中的深度也相近),那么這個假設顯然成立。但是,有些工作負載通常要求我們每次只能掃描一個對象。這可能比圖泛洪更糟糕,因為我們可能在嘗試累積對象到頁面上的過程中,反而做了更多工作,最終卻失敗了。

Green Tea 算法針對僅包含單個待掃描對象的頁面進行了特殊處理。這有助于減少性能回退,但并不能完全消除它們。

然而,要超越圖泛洪算法,所需的單頁累積數據量遠比你想象的要少。這項研究的一個意外發現是,每次僅掃描頁面 2% 的數據就能取得比圖泛洪算法更好的性能。

可用性

“綠茶”已經在最近的 Go 1.25 版本中作為實驗性功能提供,并且可以通過在構建時將環境變量 GOEXPERIMENT 設置為 greenteagc 來啟用。這不包括前述的向量加速。

我們預計在 Go 1.26 中將“綠茶”作為默認的垃圾回收器,但你仍然可以通過 GOEXPERIMENT=nogreenteagc在構建時選擇退出。Go 1.26 還將在較新的 x86 硬件上增加向量加速,并根據我們收集的反饋包含一系列的調整和改進。

如果可以,我們鼓勵你嘗試使用 Go 的最新tip版本!如果你更喜歡使用 Go 1.25,我們也同樣歡迎您的反饋。請參閱這個 GitHub 評論,其中包含一些關于我們感興趣的診斷信息、如果你可以分享的話,以及首選的反饋渠道的細節。

旅程

在結束這篇博文之前,讓我們花點時間談談我們走到今天的歷程,以及這項技術背后的人的因素。

綠茶的核心理念看似簡單,就像某個人靈光一閃的靈感火花。

但事實并非如此。“綠茶”是許多人多年來共同努力和構思的成果。Go 團隊的多位成員都參與了構思,包括 Michael Pratt、Cherry Mui、David Chase 和 Keith Randall。當時在英特爾工作的 Yves Vandriessche 的微架構見解也對設計探索起到了至關重要的作用。為了使這個看似簡單的理念得以實現,我們嘗試了許多方法,也處理了許多細節問題。

圖片圖片

時間線描繪了我們在達到今天這種狀態之前,嘗試過的一些類似想法。

這個想法的萌芽可以追溯到2018年。有趣的是,團隊里的每個人都認為最初的想法是別人提出的。

綠茶這個名字是在2024年得來的。當時,奧斯汀在日本四處尋覓咖啡館,喝了無數抹茶,并由此構思出了早期版本的原型!這個原型證明了綠茶的核心理念是可行的。從此,我們便開始了綠茶的研發之路。

在 2025 年,隨著 Michael 將綠茶項目實施并投入生產,其理念進一步發展和變化。

這需要大量的協作探索,因為綠茶算法不僅僅是一個算法,而是一個完整的設計空間。我們認為,單憑我們中的任何一個人都無法獨自駕馭它。僅僅有想法是不夠的,你還需要弄清楚細節并加以驗證。現在我們已經做到了,終于可以開始迭代了。

“綠茶”的未來是光明的。

再次,請通過設置 GOEXPERIMENT=greenteagc 來嘗試它,并讓我們知道它的效果如何!我們對這項工作感到非常興奮,并希望聽到你的聲音!

責任編輯:武曉燕 來源: TonyBai
相關推薦

2022-03-21 11:33:11

JVM垃圾回收器垃圾回收算法

2020-11-18 10:54:29

垃圾回收器演進

2009-06-18 13:59:33

Java SE 6垃圾回收器

2013-06-27 10:12:47

2022-06-02 08:37:10

架構DDDMVC

2016-08-28 14:58:52

2025-08-12 07:24:54

2025-11-03 08:46:27

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2022-01-20 10:34:49

JVM垃圾回收算法

2018-11-29 09:36:45

架構系統拆分結構演變

2017-03-03 09:26:48

PHP垃圾回收機制

2022-05-12 16:09:52

物聯網物聯網傳感器

2014-06-12 09:20:31

大數據醫療

2017-03-20 19:40:29

AndroidSwipeRefres下拉刷新

2013-01-24 11:03:30

2020-04-09 08:47:38

Java對象線程

2024-06-13 07:51:08

2024-08-20 16:27:54

2017-08-11 09:15:32

華為
點贊
收藏

51CTO技術棧公眾號

日本怡春院一区二区| 99精品国产高清一区二区麻豆| 久久久国产午夜精品 | 精品国产一区二区三| 国产一级18片视频| 色婷婷综合网| 亚洲第一视频在线观看| 三级在线视频观看| 青草在线视频| 国产午夜精品久久久久久久| 99久热re在线精品视频| 波多野结衣电车| 欧美亚韩一区| 中文字幕日韩欧美在线 | 成人午夜888| 黑丝美女久久久| 一本二本三本亚洲码| 亚洲av电影一区| 韩国欧美国产1区| 青青草原成人在线视频| 亚洲精品自拍视频在线观看| 日韩高清电影免费| 欧美一区二区久久久| 欧美精品第三页| av中文字幕电影在线看| 亚洲欧洲日产国产综合网| 国产伦精品一区二区三区照片| 在线免费看91| 久久精品一本| 国内精品久久久久伊人av| 永久免费观看片现看| 天堂成人娱乐在线视频免费播放网站| 555www色欧美视频| 欧美性猛交久久久乱大交小说| 草草影院在线| 亚洲免费观看高清完整版在线| 日韩精品欧美一区二区三区| 五月婷在线视频| 高清国产一区二区| 91青草视频久久| 中文字幕视频一区二区| 日韩精品欧美成人高清一区二区| 午夜精品在线视频| 久久久美女视频| 亚洲乱码精品| 日韩最新中文字幕电影免费看| 女女互磨互喷水高潮les呻吟| 另类春色校园亚洲| 精品国产亚洲一区二区三区在线观看| 天天摸天天舔天天操| 巨大黑人极品videos精品| 日韩欧美中文在线| 99精品人妻少妇一区二区| 激情影院在线| 亚洲国产精品久久久男人的天堂 | 欧美日韩在线直播| 亚洲视频在线观看一区二区三区| 亚洲欧美韩国| 欧美日韩美女在线| 精品中文字幕av| 亚洲精品永久免费视频| 色婷婷激情综合| 北条麻妃在线一区| 欧美日韩不卡| 欧美日韩久久久久久| 国产欧美一区二| 玖玖精品一区| 精品噜噜噜噜久久久久久久久试看| 天堂网成人在线| 视频一区在线| 日韩av在线精品| 免费无码一区二区三区| 亚洲欧美日本伦理| 一区二区国产精品视频| 精品日韩在线视频| 91精品国产麻豆国产在线观看| 久久成人一区二区| 精品无码一区二区三区电影桃花| 亚洲人妖在线| 国产精品高潮在线| 国产又大又黄又爽| 成人永久免费视频| 免费看成人片| 天天在线视频色| 一区二区欧美国产| 波多野结衣家庭教师在线播放| 亚洲综合电影| 欧美人妇做爰xxxⅹ性高电影| 亚洲理论中文字幕| 国产欧美三级电影| 影音先锋日韩有码| 久久久久亚洲AV成人| 亚洲毛片网站| 91精品国产综合久久久久久蜜臀| 超碰免费在线97| 91丨国产丨九色丨pron| 在线观看欧美激情| 大菠萝精品导航| 欧美日韩一级黄| 久久精品女同亚洲女同13| 成人激情诱惑| 久久久亚洲影院你懂的| 国产精品欧美综合| 成人小视频免费在线观看| 欧美一区二区综合| 日本动漫理论片在线观看网站| 一本色道久久综合精品竹菊| 91欧美一区二区三区| 另类尿喷潮videofree| 精品国产一区久久久| 日本中文字幕免费| 精品一区二区三区香蕉蜜桃| 久久久久久国产精品免费免费| 色网站在线看| 欧美性高潮在线| 久久国产免费视频| 成人高清电影网站| 欧日韩在线观看| wwwav网站| 国产精品另类一区| 久草青青在线观看| 中文字幕一区二区三区四区久久| 中文字幕日韩精品在线| 精品国产一区二区三区四| 国产成人在线视频免费播放| 一区二区三区av在线| 亚洲久久在线观看| 国产麻豆精品在线观看| 色姑娘综合网| 中文字幕在线中文字幕在线中三区| 日韩欧美一卡二卡| 精品女人久久久| 三级在线观看一区二区| 精品日本一区二区三区| 五月婷婷视频在线观看| 制服丝袜亚洲网站| 国产一二三av| 人人精品人人爱| 日日骚一区二区网站| 日韩性xxx| 精品亚洲va在线va天堂资源站| 久草视频精品在线| 懂色一区二区三区免费观看| 中文字幕第一页亚洲| 国产极品一区| 自拍偷拍亚洲精品| 一级黄色大毛片| 国产精品剧情在线亚洲| 欧美男女交配视频| 不卡日本视频| 国产精品日韩电影| 98在线视频| 欧美日韩国产高清一区| 五月天婷婷丁香网| 美女网站色91| 椎名由奈jux491在线播放 | 欧美日本在线一区| 久久视频一区二区三区| 麻豆精品视频在线观看免费| 亚洲国产精品www| 国产亚洲精品精品国产亚洲综合| 在线午夜精品自拍| 在线观看免费高清视频| 亚洲欧洲另类国产综合| 国内精品国产三级国产aⅴ久| 亚洲精品一区二区在线看| 亚洲一区二区三区成人在线视频精品 | 中文字幕不卡三区视频| 亚洲午夜精品久久久久久性色| 中文人妻av久久人妻18| 亚洲国产精品激情在线观看 | 高清电影一区| 日韩在线中文字幕| 国产女无套免费视频| 亚洲综合一二区| 99久久国产精| 日本va欧美va瓶| 黄色免费高清视频| youjizz欧美| 国产ts一区二区| 日本免费中文字幕在线| 日韩精品在线网站| 97人人澡人人爽人人模亚洲| 国产日韩一级二级三级| 人人爽人人爽av| 亚洲美女色禁图| 视频一区二区在线| 精品视频成人| 91成人精品网站| 嫩草香蕉在线91一二三区| 欧美大片拔萝卜| 午夜一级黄色片| 亚洲日本在线视频观看| 无码人妻精品一区二区三区温州| 麻豆精品视频在线观看视频| 精品丰满人妻无套内射| 波多野结衣的一区二区三区| 高清视频一区二区三区| 欧美日一区二区三区| 国模吧一区二区| 夜级特黄日本大片_在线| 精品国产乱码久久久久久浪潮| 中文字幕亚洲乱码熟女1区2区| 亚洲欧美日韩电影| 亚洲熟妇一区二区三区| 国产精品18久久久| 欧美黑人又粗又大又爽免费| 在线视频观看日韩| 亚洲自拍的二区三区| 色88888久久久久久影院| 成人激情电影一区二区| 欧美黑人粗大| 久久青草福利网站| 久久综合网导航| 亚洲视频在线免费观看| 成人免费观看在线视频| 欧美精品视频www在线观看| 在线观看黄网站| 亚洲国产视频a| 三级在线观看免费大全| 国产欧美一区二区在线| 午夜av免费看| 国产很黄免费观看久久| 亚欧激情乱码久久久久久久久| 欧美专区18| 国产毛片视频网站| 午夜久久久久| 国产91av视频在线观看| 欧美呦呦网站| 日产精品高清视频免费| 欧洲亚洲视频| 国产欧美日韩伦理| 欧美成人精品午夜一区二区| 国产日韩一区在线| 欧美日韩精品一区二区三区视频| 97视频免费看| 超碰97国产精品人人cao| 欧美第一黄色网| 成人福利网站| 久久不射电影网| 黄色片网站在线| 免费91在线视频| av在线免费网站| 欧美精品中文字幕一区| 在线观看三级视频| 久久亚洲精品中文字幕冲田杏梨| 黄视频网站在线看| 久久av在线看| 色av手机在线| 久久久亚洲欧洲日产国码aⅴ| 国产精品探花在线| 久久久视频精品| 96av在线| 欧美做爰性生交视频| 国产精品久久久久av电视剧| 国产精品久久久久久久天堂| 成人在线免费| 91日本视频在线| 日韩一区二区三区色| 国产不卡一区二区三区在线观看| 91精品国产自产精品男人的天堂| 国产综合欧美在线看| 欧美电影免费网站| 欧美中文娱乐网| 精品久久国产| 色呦呦网站入口| 国内综合精品午夜久久资源| 成人在线观看你懂的| 亚洲欧美视频| 国产精品视频中文字幕| 国产美女娇喘av呻吟久久| 黄色国产在线视频| 久久久久久电影| 美女视频久久久| 亚洲图片欧美一区| 中文精品久久久久人妻不卡| 欧美精品色综合| 亚洲av成人精品毛片| 一本色道久久综合狠狠躁篇怎么玩| 日本暖暖在线视频| 性欧美xxxx| se69色成人网wwwsex| 亚洲free性xxxx护士白浆| 国产精品任我爽爆在线播放| 欧美日韩系列| 欧美伊人影院| 日韩在线一级片| 国内一区二区视频| 性欧美成人播放77777| 亚洲视频香蕉人妖| 手机看片久久久| 欧美一区二区三区视频在线观看| 神马久久精品| 成人97在线观看视频| 都市激情亚洲综合| 3d动漫啪啪精品一区二区免费| 伊人久久大香线蕉综合网站| 欧美日韩一级在线| 老**午夜毛片一区二区三区 | 国产成年精品| 欧美日韩大片一区二区三区| 欧美国产91| 一级片视频免费观看| av一本久道久久综合久久鬼色| 久久精品—区二区三区舞蹈| 亚洲激情男女视频| 青青草视频在线观看免费| 日韩欧美卡一卡二| 国产69久久| 国产+人+亚洲| 免费一级欧美片在线观看网站| 欧美日本韩国一区二区三区| 亚洲啊v在线观看| 国产精品wwwww| 国产91精品在线观看| 国内毛片毛片毛片毛片毛片| 婷婷综合另类小说色区| 亚洲天堂视频在线播放| 欧美精品一区二区三区在线播放| 69视频在线观看| 国产成人精品电影| av男人一区| 欧美aaa在线观看| 老色鬼精品视频在线观看播放| 国产伦精品一区二区三区妓女| 亚洲va欧美va人人爽午夜 | 日韩欧美高清一区| 日本视频在线观看| 国产激情999| 岛国精品一区| 国产一区二区三区乱码| 久久99精品一区二区三区三区| 蜜乳av中文字幕| 精品二区三区线观看| 国产乱淫av免费| 久久偷看各类女兵18女厕嘘嘘| 日韩成人影音| 任我爽在线视频精品一| 99视频精品| 又色又爽又黄18网站| 亚洲黄色尤物视频| 国产精品人妻一区二区三区| 久久精品电影网| 四虎永久精品在线| 日韩.欧美.亚洲| 丝袜美腿亚洲色图| 丰满少妇一区二区三区| 岛国视频午夜一区免费在线观看 | 日韩av在线一区二区| 国产乱码午夜在线视频| 国产精品成人一区二区三区| 亚洲欧洲一区二区天堂久久| 91传媒理伦片在线观看| 婷婷六月综合网| 色婷婷av一区二区三区之红樱桃 | 日韩免费av片| 亚洲国产精品高清久久久| 人人草在线视频| 久久久福利视频| 久久久精品五月天| 中文字幕免费视频| 欧美日韩在线亚洲一区蜜芽| youjizz在线播放| 国产在线观看精品| 午夜电影亚洲| 制服丝袜第一页在线观看| 狠狠综合久久av一区二区小说| 深夜福利免费在线观看| 久久久久久久网站| 亚州综合一区| 免费av网址在线| 亚洲欧洲韩国日本视频| www香蕉视频| 青青久久av北条麻妃黑人| 国产精品中文字幕亚洲欧美| 午夜免费高清视频| 亚洲免费观看高清完整版在线观看| 亚洲精品久久久久久久久久| 日韩女在线观看| 99精品视频在线| 国产麻豆剧传媒精品国产av| 欧美性猛交xxx| 蜜芽在线免费观看| 国产日韩一区欧美| 玖玖玖国产精品| 欧美特级一级片| 亚洲国产精品久久精品怡红院| av免费在线一区| 神马午夜伦理影院| 91麻豆国产福利在线观看| 国产在线一级片| 欧美精品一本久久男人的天堂| 免费看日本一区二区| 欧美日韩在线观看不卡| 亚洲电影一区二区三区| 可以在线观看的黄色| 91精品黄色| 久久婷婷影院| 国产午夜精品理论片| 亚洲欧美综合图区|