<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 8.11 過去、現在與未來 ## 8.14.1 被采納的方案 我們現在來詳細回顧一下 Go 中 GC 在各個版本上的演進歷史。 ### Go 1:樸素標記清掃 在 Go 1 的時代,盡管所有的用戶代碼都是并發執行的,但是一旦垃圾回收器開始進行垃圾回收工作時,所有的用戶代碼都會停止執行,而且垃圾回收器僅在一個線程上執行,這時是最原始的垃圾回收器的實現,即單線程版的三色標記清掃。 ### Go 1.1, 1.3:并行清掃與精準標記 在 Go 1.3 時候,官方將三色標記清掃算法的垃圾回收代碼改為并行,從而縮短了用戶代碼的停止時間,但是這仍然會造成大量的空隙,如果用戶代碼是一個 Web 應用,且正在處理一個非常重要的請求,則會對請求延遲造成巨大的影響。 ![](https://golang.design/under-the-hood/assets/gc1.png)**圖 1: Go 1 與 1.3 的垃圾回收器** ### Go 1.5:并發回收 為了解決 STW 問題,官方在 Go 1.5 開始使用 Dijkstra 寫屏障技術讓垃圾回收與用戶代碼得以并行執行。 從而只有在執行寫屏障和很短一段時間內才需要進行 STW。 ### Go 1.6:狀態化回收器與位圖技術 TODO: ### Go 1.7:獨立棧收縮 TODO: ### Go 1.8, 1.9:混合寫屏障 Go 團隊在 1.8 引入混合屏障將 STW 進一步縮短,幾乎解決了 STW 的問題。 ![](https://golang.design/under-the-hood/assets/gc2.png)**圖 1: Go 1.5 與 1.8 的垃圾回收器** ### Go 1.10, 1.11:雙限度機制 ### Go 1.12:終止奇點 ### Go 1.13:清道夫 ### Go 1.14:頁分配器 到了 Go 1.14,由于頁分配器的引入,向操作系統歸還內存的操作頁完全得到并發。 ![](https://golang.design/under-the-hood/assets/gc3.png)**圖 1: Go 1.13 與 1.14 的垃圾回收器** ## 8.14.2 被拋棄的方案 ### 并發棧重掃 早期的 Go 選擇了在 STW 期間,重新對棧進行掃描。 垃圾回收器首先在 GC 循環開始時掃描所有棧從而收集根。 但是如果沒有棧的寫屏障,我們便無法確保堆棧以后不會包含對白色對象的引用, 所以掃描棧只有黑色,直到其 Goroutine 再次執行, 因此它保守地恢復為灰色。從而在循環結束時, 垃圾回收器必須重新掃描灰色堆棧以使其變黑并完成標記任何剩余堆指針。 由于必須保證棧在此期間不會繼續更改,因此重新掃描過程在 STW 時發生。 實踐表明,棧的重掃需要消耗 10 - 100 毫秒的時間。 因為存在重掃的問題,除了引入混合屏障來消除重掃這一過程外, 有另一種做法可以提高重掃過程的性能,那就是將重掃的過程并發執行, 然而這一方案并沒有得以實現。原因很簡單:實現過程相比引入混合屏障而言十分復雜, 而且引入混合屏障能夠消除重掃這一過程,將簡化垃圾回收的步驟。 ### ROC 請求制導式回收器可謂成也假設敗也假設。請求制導假設非常符合直覺,但在實現上,由于垃圾回收器必須確保是否有 Goroutine 私有指針被寫入公共對象,因此寫屏障必須一直打開,這也就產生了該方法的致命缺點:昂貴的寫屏障及其帶來的緩存未命中,這也是這一設計最終沒有被采用的主要原因。 ### 傳統分代 GC 實踐證明請求制導回收器性能并沒有帶來顯著提升之后,作為備選方案,Go 團隊還嘗試了實現傳統的分代式 GC。但最終同樣發現分代假設并不適用于 Go 的運行棧機制,年輕代對象在棧上就已經死亡,掃描本就該回收的執行棧并沒有為由于分代假設帶來明顯的性能提升,也成為了這一方案最終沒有被采用的主要原因。 ## 8.14.3 展望 ### 標記輔助時間過長 ### 清掃時間過長 ### 大規模場景下性能低下 ### 對齊導致的內存浪費 ### 可能的進化方向
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看