<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                首先我們先來了解下什么是垃圾回收。 什么是垃圾回收? 內存管理是程序員開發應用的一大難題。傳統的系統級編程語言(主要指C/C++)中,程序開發者必須對內存小心的進行管理操作,控制內存的申請及釋放。因為稍有不慎,就可能產生內存泄露問題,這種問題不易發現并且難以定位,一直成為困擾程序開發者的噩夢。 如何解決這個頭疼的問題呢? 過去一般采用兩種辦法: * 內存泄露檢測工具。這種工具的原理一般是靜態代碼掃描,通過掃描程序檢測可能出現內存泄露的代碼段。然而檢測工具難免有疏漏和不足,只能起到輔助作用。 * 智能指針。這是 c++ 中引入的自動內存管理方法,通過擁有自動內存管理功能的指針對象來引用對象,是程序員不用太關注內存的釋放,而達到內存自動釋放的目的。這種方法是采用最廣泛的做法,但是對程序開發者有一定的學習成本(并非語言層面的原生支持),而且一旦有忘記使用的場景依然無法避免內存泄露。 為了解決這個問題,后來開發出來的幾乎所有新語言(java,python,php等等)都引入了語言層面的自動內存管理 – 也就是語言的使用者只用關注內存的申請而不必關心內存的釋放,內存釋放由虛擬機(virtual machine)或運行時(runtime)來自動進行管理。而這種對不再使用的內存資源進行自動回收的行為就被稱為垃圾回收。 常用的垃圾回收的方法: * 引用計數(reference counting) 這是最簡單的一種垃圾回收算法,和之前提到的智能指針異曲同工。對每個對象維護一個引用計數,當引用該對象的對象被銷毀或更新時被引用對象的引用計數自動減一,當被引用對象被創建或被賦值給其他對象時引用計數自動加一。當引用計數為0時則立即回收對象。 這種方法的優點是實現簡單,并且內存的回收很及時。這種算法在內存比較緊張和實時性比較高的系統中使用的比較廣泛,如`ios cocoa`框架,php,python等。 但是簡單引用計數算法也有明顯的缺點: 1. 頻繁更新引用計數降低了性能。 一種簡單的解決方法就是編譯器將相鄰的引用計數更新操作合并到一次更新;還有一種方法是針對頻繁發生的臨時變量引用不進行計數,而是在引用達到0時通過掃描堆棧確認是否還有臨時對象引用而決定是否釋放。等等還有很多其他方法,具體可以參考這里。 2. 循環引用。 當對象間發生循環引用時引用鏈中的對象都無法得到釋放。最明顯的解決辦法是避免產生循環引用,如cocoa引入了strong指針和weak指針兩種指針類型。或者系統檢測循環引用并主動打破循環鏈。當然這也增加了垃圾回收的復雜度。 * 標記-清除(mark and sweep) 標記-清除(mark and sweep)分為兩步,標記從根變量開始迭代得遍歷所有被引用的對象,對能夠通過應用遍歷訪問到的對象都進行標記為“被引用”;標記完成后進行清除操作,對沒有標記過的內存進行回收(回收同時可能伴有碎片整理操作)。 這種方法解決了引用計數的不足,但是也有比較明顯的問題:每次啟動垃圾回收都會暫停當前所有的正常代碼執行,回收時,系統響應能力大大降低!當然后續也出現了很多`mark&sweep`算法的變種(如三色標記法)優化了這個問題。 * 分代搜集(generation) java的jvm 就使用的分代回收的思路。在面向對象編程語言中,絕大多數對象的生命周期都非常短。分代收集的基本思想是,將堆劃分為兩個或多個稱為代(generation)的空間。 新創建的對象存放在稱為新生代(young generation)中(一般來說,新生代的大小會比 老年代小很多),隨著垃圾回收的重復執行,生命周期較長的對象會被提升(promotion)到老年代中(這里用到了一個分類的思路,這個是也是科學思考的一個基本思路)。 因此,新生代垃圾回收和老年代垃圾回收兩種不同的垃圾回收方式應運而生,分別用于對各自空間中的對象執行垃圾回收。新生代垃圾回收的速度非常快,比老年代快幾個數量級,即使新生代垃圾回收的頻率更高,執行效率也仍然比老年代垃圾回收強,這是因為大多數對象的生命周期都很短,根本無需提升到老年代。 Golang GC 時會發生什么? `Golang 1.5`后,采取的是“非分代的、非移動的、并發的、三色的”標記清除垃圾回收算法。 golang 中的 gc 基本上是標記清除的過程: [![](https://github.com/KeKe-Li/For-learning-Go-Tutorial/raw/master/src/images/2.jpg)](https://github.com/KeKe-Li/For-learning-Go-Tutorial/blob/master/src/images/2.jpg) golang 的垃圾回收是基于標記清掃算法,這種算法需要進行 STW(stop the world),這個過程就會導致程序是卡頓的,頻繁的 GC 會嚴重影響程序性能. golang 在此基礎上進行了改進,通過三色標記清掃法與寫屏障來減少 STW 的時間. gc的過程一共分為四個階段: 1. 棧掃描(開始時STW),所有對象最開始都是白色. 2. 從 root開始找到所有可達對象(所有可以找到的對象),標記為灰色,放入待處理隊列。 3. 遍歷灰色對象隊列,將其引用對象標記為灰色放入待處理隊列,自身標記為黑色。 4. 清除(并發) 循環步驟3直到灰色隊列為空為止,此時所有引用對象都被標記為黑色,所有不可達的對象依然為白色,白色的就是需要進行回收的對象。 三色標記法相對于普通標記清掃,減少了 STW 時間. 這主要得益于標記過程是 "on-the-fly" 的,在標記過程中是不需要 STW 的,它與程序是并發執行的,這就大大縮短了STW的時間. Golang gc 優化的核心就是盡量使得 STW(Stop The World) 的時間越來越短。 詳細的Golang的GC介紹可以參看[Golang垃圾回收](https://github.com/KeKe-Li/For-learning-Go-Tutorial/blob/master/src/spec/02.0.md). 寫屏障: 當標記和程序是并發執行的,這就會造成一個問題. 在標記過程中,有新的引用產生,可能會導致誤清掃. 清掃開始前,標記為黑色的對象引用了一個新申請的對象,它肯定是白色的,而黑色對象不會被再次掃描,那么這個白色對象無法被掃描變成灰色、黑色,它就會最終被清掃,而實際它不應該被清掃. 這就需要用到屏障技術,golang采用了寫屏障,其作用就是為了避免這類誤清掃問題. 寫屏障即在內存寫操作前,維護一個約束,從而確保清掃開始前,黑色的對象不能引用白色對象.
                  <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>

                              哎呀哎呀视频在线观看