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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## **jvm怎么判斷哪些對象(已經死亡)應該回收呢?** 在Java中,判斷一個對象是否“死亡”通常是指判斷對象是否可以被垃圾回收。JVM提供了幾種機制來進行此類判斷。 ### 1\. 引用計數法 **定義**:每個對象都有一個引用計數器,當有一個地方引用它時,計數器加1,當引用失效時,計數器減1。任何時刻引用計數器為0的對象就是不再被引用的,可以被認為是“死亡”。 **缺點**:無法解決循環引用的問題,即兩個對象互相引用但沒有其他地方引用它們時,引用計數器不會歸零,無法被回收。 ### 2\. 可達性分析法(Reachability Analysis) 這是JVM判斷對象是否可以被回收的主流算法,通過一系列稱為“GC Roots”的對象作為起始點,從這些節點開始向下搜索,搜索所走過的路徑稱為引用鏈。如果一個對象到GC Roots沒有任何引用鏈相連,則該對象是不可達的,可以被垃圾回收。 ## **哪些對象可以作為根對象(GC Roots)** 可以作為GC Roots的對象類別: 1. **虛擬機棧(棧幀中的本地變量表)中引用的對象**: * 任何在當前線程棧中活躍的局部變量和輸入參數(這些變量存儲在棧幀的本地變量表中)都可以作為GC Roots。 ~~~ java復制代碼public void method() { Object obj = new Object(); // obj是GC Root } ~~~ 2. **方法區中的類靜態屬性引用的對象**: * 類靜態屬性(static修飾的變量)是全局引用,它們存儲在方法區中,這些屬性引用的對象也可以作為GC Roots。 ~~~ java復制代碼public class MyClass { private static Object obj = new Object(); // obj是GC Root } ~~~ 3. **方法區中的常量引用的對象**: * 方法區中的常量引用,如字符串常量池中的字符串(String Pool)也可以作為GC Roots。 ~~~ java復制代碼public class MyClass { private static final String CONSTANT = "constant"; // CONSTANT是GC Root } ~~~ 4. **本地方法棧中JNI(即一般說的Native方法)引用的對象**: * 本地方法接口(Java Native Interface,JNI)中持有的引用對象(通過native方法調用C/C++代碼中持有的Java對象引用)也可以作為GC Roots。 ~~~ c復制代碼// C/C++代碼中使用的Java對象引用 jobject obj = (*env)->NewObject(env, cls, methodID); ~~~ 5. **活動線程(Active Threads)**: * 所有活動的線程(正在運行或等待的線程)本身及其持有的對象引用也可以作為GC Roots。 ~~~ java復制代碼Thread t = new Thread(new Runnable() { public void run() { // 線程中的對象引用 } }); t.start(); // t是GC Root ~~~ 6. **系統類加載器(System Class Loader)**: * 系統類加載器及其加載的類也是GC Roots。 7. **常駐JVM的JNI全局引用**: * 通過JNI調用的全局引用(Global References)在JVM生命周期內一直存在,也是GC Roots。 8. **Java虛擬機內部的關鍵數據結構**: * 比如反映Java調用棧的相關數據結構等。 ## **CMS和G1都是有一個并發標記的過程,并發標記要解決什么問題?帶來了什么問題?怎么解決這些問題呢?** CMS(Concurrent Mark-Sweep)和G1(Garbage-First)垃圾收集器在Java中都有一個并發標記過程。并發標記的主要目標是標記出所有存活的對象,以便在隨后的垃圾收集過程中進行回收。并發標記在運行時與應用程序線程同時執行,旨在減少垃圾收集對應用程序響應時間的影響。然而,并發標記也帶來了一些問題,需要通過特定的技術手段來解決。 ### 并發標記的目標和問題 #### 目標 * **減少停頓時間**:通過與應用程序線程并發運行,盡量減少垃圾收集對應用程序的停頓時間。 * **提高應用響應性**:避免長時間的暫停,提高應用程序的響應性。 #### 主要問題 1. **浮動垃圾(Floating Garbage)**: * **問題**:由于并發標記與應用程序線程同時運行,在標記過程中可能會有對象變為不可達,但這些對象在本次標記周期內不會被標記為垃圾,從而無法回收。 * **影響**:這部分垃圾只能等到下一次GC周期才能被回收,導致當前回收效率降低。 2. **標記準確性**: * **問題**:在并發標記過程中,應用程序線程可能會修改對象引用,使得標記結果不準確(標記漏掉存活對象或錯誤標記垃圾對象)。 * **影響**:需要保證標記過程能夠正確反映對象的可達性,避免誤回收或漏回收。 ### 解決方法 #### CMS(Concurrent Mark-Sweep)解決方法 1. **Initial Marking(初始標記)**: * **工作**:暫停所有應用程序線程,標記從根節點(GC Roots)直接可達的對象。 * **停頓時間**:短暫停頓,因為僅標記根對象。 2. **Concurrent Marking(并發標記)**: * **工作**:與應用程序線程并發運行,從初始標記的根對象開始標記所有可達對象。 * **停頓時間**:無,完全并發。 3. **Remarking(重新標記)**: * **工作**:再次暫停應用程序線程,標記在并發標記階段發生變化的對象引用,確保標記準確性。 * **停頓時間**:相對較長,但比完全停頓的標記時間短。 4. **Concurrent Sweeping(并發清理)**: * **工作**:與應用程序線程并發運行,清理未標記的對象。 * **停頓時間**:無,完全并發。 #### G1(Garbage-First)解決方法 1. **Initial Marking(初始標記)**: * **工作**:暫停應用程序線程,標記從根節點(GC Roots)直接可達的對象,同時標記已知的存活對象。 * **停頓時間**:短暫停頓,因為僅標記根對象。 2. **Concurrent Marking(并發標記)**: * **工作**:與應用程序線程并發運行,從初始標記的根對象開始標記所有可達對象。 * **停頓時間**:無,完全并發。 3. **Final Marking(最終標記)**: * **工作**:暫停應用程序線程,處理在并發標記階段發生變化的對象引用,確保標記準確性。 * **停頓時間**:短暫停頓,類似CMS的重新標記。 4. **Live Data Counting and Evacuation(存活數據計數和搬遷)**: * **工作**:與應用程序線程并發運行,統計存活對象,并在收集階段將存活對象搬遷到新的內存區域,釋放舊的內存區域。 * **停頓時間**:視具體實現而定。 ### 具體問題解決方法 1. **浮動垃圾的處理**: * **CMS**:浮動垃圾不會在當前GC周期內被回收,只能等待下一次GC。因此,CMS通常需要更多的內存來應對浮動垃圾。 * **G1**:G1通過分區(Region)和回收(Evacuation)的方式,較好地處理浮動垃圾,盡量減少未回收的垃圾數量。 2. **標記準確性的保證**: * **CMS**:通過重新標記階段確保在并發標記過程中發生變化的引用得到正確處理。 * **G1**:通過最終標記階段和SATB(Snapshot-At-The-Beginning)算法,確保并發標記的準確性。SATB在并發標記開始時對引用關系進行快照,確保標記過程中的引用變化能夠被正確處理。 ### 總結 * **并發標記的目標**:減少GC停頓時間,提高應用程序的響應性。 * **主要問題**:浮動垃圾和標記準確性。 * **解決方法**: * CMS通過初始標記、并發標記、重新標記和并發清理來處理。 * G1通過初始標記、并發標記、最終標記和搬遷來處理,同時使用SATB算法保證標記準確性。
                  <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>

                              哎呀哎呀视频在线观看