精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

亚洲精品va| 成人豆花视频| 国产女主播一区| 成人信息集中地欧美| 欧美成人综合色| 日韩欧美国产大片| 欧美另类高清zo欧美| 日韩成人手机在线| 国产鲁鲁视频在线观看免费| 国产在线视频不卡二| 77777亚洲午夜久久多人| 999福利视频| 久久男人av| 91精品国产福利| 色婷婷综合久久久久中文字幕 | 国产成人无码专区| 国产精品mm| 中文字幕亚洲色图| 少妇毛片一区二区三区| 欧美大片91| 欧美视频第二页| 91免费视频网站在线观看| 黄色网址在线免费播放| 久久美女高清视频| 国产精品对白刺激久久久| 中日韩在线观看视频| 夜夜嗨av一区二区三区网站四季av| 中文字幕欧美专区| 无码h肉动漫在线观看| 亚洲日本视频在线| 欧美一区二区三区人| 亚洲老女人av| 巨胸喷奶水www久久久| 亚洲va在线va天堂| 国产一区 在线播放| 日本亚洲精品| 国产精品伦一区| 日韩精品久久一区二区三区| 日本一二三区在线视频| 99re视频精品| 国产一区二区免费电影| 亚洲精品无amm毛片| 国产精品白丝av| 亚洲va欧美va国产综合剧情| 在线观看免费观看在线| 国产精品无码2021在线观看| aa视频在线观看| 最新不卡av在线| 亚洲精品电影在线一区| 福利在线观看| 国产精品无圣光一区二区| 欧美日韩精品免费看| 亚洲三区在线播放| 91视视频在线观看入口直接观看www | 国产又粗又猛又爽| 久久精品噜噜噜成人av农村| 国产精品日韩欧美| 亚洲天堂网在线观看视频| 欧美96一区二区免费视频| 国产精品欧美一区二区三区奶水| 波多野结衣二区三区| 日韩激情在线观看| 国产一区在线播放| a毛片在线免费观看| 国产高清在线精品| 精品国产aⅴ麻豆| 日本一区高清| 国产精品丝袜黑色高跟| 制服丝袜综合日韩欧美| 丝袜在线观看| 午夜av区久久| 妺妺窝人体色www在线观看| 欧美xxx性| 欧美男人的天堂一二区| 午夜诱惑痒痒网| 日韩精品三级| 日韩福利视频在线观看| 国产jjizz一区二区三区视频| 日韩成人激情| 另类专区欧美制服同性| 日本污视频在线观看| 久久伊人亚洲| 2022国产精品| 欧美色视频免费| 中文字幕欧美一区| 国产精品久久久久9999爆乳| 日韩伦理三区| 日韩一区二区在线观看视频播放| 稀缺小u女呦精品呦| 视频一区中文| 欧美成人精品在线播放| 日韩在线视频不卡| 韩国视频一区二区| 韩国成人av| 亚洲图片88| 午夜精品一区在线观看| 一道本在线免费视频| silk一区二区三区精品视频| 亚洲天堂男人天堂| 色在线观看视频| 久久亚洲风情| 99国内精品久久久久久久软件| 四虎影视精品成人| 亚洲人成影院在线观看| 欧美黄色一级片视频| 亚洲国产高清在线观看| 亚洲香蕉成视频在线观看| 久久亚洲国产成人精品性色| 日本女优在线视频一区二区| 国产69精品久久久久9999apgf| 成人高清免费在线播放| 亚洲成在人线在线播放| 国产精品自拍视频在线| 五月天亚洲一区| 九九热这里只有精品6| 久久久精品毛片| 成人福利视频网站| 成人短视频在线看| 日韩一区二区三区在线免费观看 | 亚洲影院免费| 999国内精品视频在线| 韩日在线视频| 欧美日韩在线视频一区| 黄页网站在线看| 99国产精品免费视频观看| 日韩美女免费视频| 亚洲欧美自偷自拍| 性做久久久久久| 男人的天堂免费| 91精品人妻一区二区三区蜜桃2| 欧美成人家庭影院| 亚洲欧美另类在线观看| 日本少妇性生活| 懂色av一区二区夜夜嗨| av动漫免费观看| 四虎影视国产精品| 中文国产成人精品久久一| www.国产一区二区| xf在线a精品一区二区视频网站| 国产曰肥老太婆无遮挡| **爰片久久毛片| 九九九久久久久久| www.午夜激情| 亚洲成人一区在线| jjzz黄色片| 伊人影院久久| 国产欧美精品一区二区三区| av午夜在线观看| 亚洲激情久久久| 特一级黄色大片| 国产不卡视频一区二区三区| 四虎4hu永久免费入口| 榴莲视频成人app| 欧美大尺度激情区在线播放| av av片在线看| 一区二区激情视频| 欧美久久久久久久久久久| 黄色av日韩| 久久福利电影| 成人涩涩视频| 日韩在线www| 国产富婆一级全黄大片| 亚洲成人免费在线| 国产美女喷水视频| 日韩高清中文字幕一区| 正在播放91九色| 亚洲三级av| 欧美在线激情视频| 成人在线免费视频| 7777精品伊人久久久大香线蕉完整版 | 亚洲天堂美女视频| 亚洲一区二区毛片| 日韩精品久久久| 欧美经典影片视频网站| 韩日精品中文字幕| 国产在线观看黄| 91精品国产综合久久久久久久 | 欧美一级艳片视频免费观看| 国产亚洲精品久久777777| 91在线观看地址| 国产精品自拍视频在线| 激情欧美一区二区三区| 蜜桃网站成人| 国产精品高清一区二区| 777精品视频| www.91在线| 精品久久人人做人人爽| 男人的天堂av网站| 亚洲男人天堂av网| 在线免费观看成年人视频| 麻豆精品久久久| 日韩网站在线免费观看| 欧美一区电影| 97se亚洲综合| 草民电影神马电影一区二区| 欧美日韩xxxxx| 国产小视频在线| 日韩精品在线网站| 中文字幕+乱码+中文乱码91| 亚洲最大色网站| 99久久99久久精品免费看小说.| 国产成人在线色| 亚洲人辣妹窥探嘘嘘| 伊人蜜桃色噜噜激情综合| 亚洲色图自拍| 亚洲精品亚洲人成在线观看| 95av在线视频| 成人国产激情| 538国产精品一区二区在线| 国产精品一区二区三区视频网站| 亚洲视频第一页| 日本精品一二区| 日韩片之四级片| 在线免费观看视频网站| 日韩欧美亚洲成人| 精品在线视频观看| 1000精品久久久久久久久| 久久久久久久毛片| av成人动漫在线观看| 精品国产一二区| 国产麻豆视频精品| 中文字幕国内自拍| 亚洲综合社区| 狠狠干 狠狠操| 欧美bbbbb性bbbbb视频| 久久蜜桃精品| 成 年 人 黄 色 大 片大 全| 女人天堂亚洲aⅴ在线观看| 亚洲日本欧美在线| 欧美军人男男激情gay| 久久精品国产美女| 老司机aⅴ在线精品导航| 国产不卡一区二区在线观看| 九色精品蝌蚪| 91日本视频在线| 玖玖精品在线| 国产欧美一区二区三区视频| 我爱我色成人网| 欧洲成人免费视频| 伊人久久视频| 欧洲成人午夜免费大片| www视频在线观看| 国内精品久久久久久久久| 国精一区二区三区| 欧美交受高潮1| 啦啦啦中文在线观看日本| 欧美第一淫aaasss性| 亚洲无线看天堂av| 欧美国产日本在线| 免费看电影在线| 久久久欧美精品| 国产精品一区二区日韩| 97人人做人人爱| 中文在线аv在线| 热久久99这里有精品| 国产一区一一区高清不卡| 国产精品久久久久久久久久久久 | 蜜臀精品一区二区三区在线观看| 成人黄色一区二区| 日本美女一区二区三区| 色婷婷.com| 国产精品系列在线观看| 成人区人妻精品一区二| 99久久伊人久久99| 久久久无码人妻精品一区| 国产午夜精品美女毛片视频| 潮喷失禁大喷水aⅴ无码| 综合亚洲深深色噜噜狠狠网站| 中文字幕另类日韩欧美亚洲嫩草| 亚洲激情中文1区| 日本一区二区不卡在线| 日韩欧美亚洲成人| 国产精品玖玖玖| 精品免费视频.| 激情在线视频| 不卡毛片在线看| 天堂√8在线中文| 国产日韩欧美在线| 国产精品毛片视频| 日韩久久久久久久| 久久日文中文字幕乱码| 国产玉足脚交久久欧美| 另类图片国产| 激情图片中文字幕| 99久久夜色精品国产网站| 懂色av粉嫩av浪潮av| 一级精品视频在线观看宜春院| 色婷婷av国产精品| 欧美日韩国产中文| 午夜激情在线视频| 精品国内亚洲在观看18黄| yellow在线观看网址| 国产精品亚发布| 高清一区二区三区| 亚洲精品一品区二品区三品区| 午夜国产精品视频| 美女黄色片视频| 国产99久久久精品| 久久久免费看片| 亚洲国产乱码最新视频| 中文字幕日韩经典| 亚洲国产精品专区久久| 欧美边添边摸边做边爱免费| 2018日韩中文字幕| 秋霞一区二区三区| 亚洲图片在线观看| 亚洲综合国产| 97精品人人妻人人| 自拍偷在线精品自拍偷无码专区| 日韩精品在线观看免费| 日韩视频免费直播| 在线免费看黄网站| 日韩免费观看在线观看| 丁香综合av| 精品嫩模一区二区三区| 青青草97国产精品免费观看| 野外性满足hd| 亚洲国产精品一区二区www在线| 国产精品女人久久久| 亚洲午夜av久久乱码| 丁香花电影在线观看完整版| 成人黄色片在线| 欧美日韩中字| 国产免费一区二区三区视频| 国产不卡视频一区| 中文字幕在线观看成人| 欧美三级欧美一级| 成人三级黄色免费网站| 2021国产精品视频| 久久久久久久久久久久久久久久久久久久| 艳母动漫在线观看| 久久99热这里只有精品| 国产无遮挡在线观看| 色丁香久综合在线久综合在线观看| 欧美特黄一级视频| 久久欧美在线电影| 国产成人tv| 国产不卡一区二区视频| 丰满白嫩尤物一区二区| 精品少妇久久久| 欧美大片日本大片免费观看| 怡红院在线观看| 成人区精品一区二区| 国产精品www994| 成人做爰69片免费| 亚洲高清免费一级二级三级| 成人免费视频国产免费麻豆| 欧美大学生性色视频| 国产精品qvod| 亚洲 高清 成人 动漫| 91色视频在线| 黄色免费av网站| 国产小视频91| 精品自拍视频| 桥本有菜av在线| 国产成人av一区二区三区在线观看| avtt天堂在线| 亚洲成人免费在线视频| 男人久久天堂| 亚洲aⅴ天堂av在线电影软件| 久久er精品视频| 欧美爱爱免费视频| 欧美大片日本大片免费观看| 深夜在线视频| 先锋在线资源一区二区三区| 激情综合网天天干| 国产在线拍揄自揄拍| 亚洲国产中文字幕久久网| 中文字幕人成乱码在线观看| 秋霞在线观看一区二区三区| 老司机午夜精品| 青草影院在线观看| 亚洲福利视频免费观看| 婷婷六月国产精品久久不卡| 亚洲一区二区在线看| 国产美女娇喘av呻吟久久| 国产91av视频| 中文字幕国产精品久久| 成人精品视频在线观看| 黄色一级片在线看| 久久久久88色偷偷免费| 国产情侣自拍小视频| 91精品国产91久久久久| 日本高清免费电影一区| 又黄又色的网站| 91黄视频在线观看| 在线观看的网站你懂的| 蜜桃视频在线观看成人| 狠狠色伊人亚洲综合成人| 在线能看的av| 精品国偷自产在线视频| 综合亚洲自拍| 日本黄色www| 欧洲亚洲精品在线| 日本无删减在线| 亚洲一区高清| 97久久精品人人爽人人爽蜜臀| 国产一区二区视频免费观看| 91大神在线播放精品| 亚洲国产精品成人|