JVM記憶體回收機制演算法總結

來源:互聯網
上載者:User

本文系轉載,原文地址:http://blog.csdn.net/willfcareer/archive/2010/08/23/5833082.aspx

Java虛擬機器垃圾收集器分析

1 、使用中的物件

l  追蹤 root 對象演算法: 深度追蹤 root 對象,將 heap 中所有被引用到的 root 做標誌,所有未被標誌的對象視為非使用中的物件,所佔用的空間視為非活動記憶體。

2 、常用演算法

l  Copy 演算法

1  方法:將記憶體分為兩個地區( from space 和 to space )。所有的對象分配記憶體都分配到 from space 。在清理非使用中的物件階段,把所有標誌為活動的對象, copy 到 to
space ,之後清楚 from space 空間。然後互換 from sapce 和 to space 的身份。既原先的 from space 變成 to
sapce ,原先的 to space 變成 from space 。每次清理,重複上述過程。

2  優點: copy 演算法不理會非使用中的物件, copy 數量僅僅取決為使用中的物件的數量。並且在 copy 的同時,整理了 heap 空間,即, to
space 的空間使用始終是連續的,記憶體使用量效率得到提高。

3  缺點:劃分 from space 和 to space ,記憶體的使用率是 1 / 2 。一般在 Young
Generation 中使用。

l  Compaction 演算法

1  方法:在清理非使用中的物件階段,刪除非使用中的物件佔用記憶體,並且把使用中的物件向 heap 的底部移動,直到所有的使用中的物件被移到 heap 的一側。

2  優點:無須劃分 from sapce 和 to space ,提高記憶體的使用率。並且 compaction 後的記憶體空間也是連續分配的。

3  缺點:該演算法相對比較複雜。一般在 Tenured Generation 中使用

 

1、  記憶體劃分

l  Young Generation

1  生命週期很短的對象,歸為 young generation 。由於生命週期很短,這部分對象在 gc 的時候,很大部分的對象已經成為非使用中的物件。因此針對 young 
generation 的對象,採用 copy 演算法,只需要將少量的存活下來的對象 copy 到 to space 。存活的對象數量越少,那麼 copy 演算法的效率越高。

2  young generation 的 gc 稱為 minor gc 。經過數次 minor
gc ,依舊存活的對象,將被移出 young generation ,移到 tenured generation

3  young generation 分為:

1  eden :每當對象建立的時候,總是被分配在這個地區

2  survivor1 : copy 演算法中的 from space

3  survivor2 : copy 演算法中的 to sapce (備忘:其中 survivor1 和 survivor2 的身份在每次 minor
gc 後被互換)

4  minor gc 的時候,會把 eden+survivor1(2) 的對象 copy 到 survivor2(1) 去。

l  Tenured Generation

1  生命週期較長的對象,歸入到 tenured generation 。一般是經過多次 minor gc ,還 依舊存活的對象,將移入到 tenured
generation 。(當然,在 minor gc 中如果存活的對象的超過 survivor 的容量,放不下的對象會直接移入到 tenured generation )

2  tenured generation 的 gc 稱為 major gc ,就是通常說的 full
gc 。

3  採用 compactiion 演算法。由於 tenured generaion 地區比較大,而且通常對象生命週期都比較常, compaction 需要一定時間。所以這部分的 gc 時間比較長。

4  minor gc 可能引發 full gc 。當 eden + from space 的空間大於 tenured
generation 區的剩餘空間時,會引發 full gc 。這是悲觀演算法,要確保 eden + from space 的對象如果都存活,必須有足夠的 tenured generation 空間存放這些對象。

l  Permanet Generation

1  該地區比較穩定,主要用於存放 classloader 資訊,比如類資訊和 method 資訊。

                    2 對於 spring hibernate 這些需要動態類型支援的架構,這個地區需要足夠的空間。

演算法補充:

基本回收演算法

  1. 引用計數(Reference Counting)
    比較古老的回收演算法。原理是此對象有一個引用,即增加一個計數,刪除一個引用則減少一個計數。記憶體回收時,只用收集計數為0的對象。此演算法最致命的是無法處理循環參考的問題。
  2. 標記-清除(Mark-Sweep)
    此演算法執行分兩階段。第一階段從引用根節點開始標記所有被引用的對象,第二階段遍曆整個堆,把未標記的對象清除。此演算法需要暫停整個應用,同時,會產生記憶體片段。
  3. 複製(Copying)
    此演算法把記憶體空間劃為兩個相等的地區,每次只使用其中一個地區。記憶體回收時,遍曆當前使用地區,把正在使用中的對象複製到另外 一個地區中。次演算法每次只處理正在使用中的對象,因此複製成本比較小,同時複製過去以後還能進行相應的記憶體整理,不過出現“片段”問題。當然,此演算法的缺 點也是很明顯的,就是需要兩倍記憶體空間。
  4. 標記-整理(Mark-Compact)
    此演算法結合了“標記-清除”和“複製”兩個演算法的優點。也是分兩階段,第一階段從根節點開始標記所有被引用對象,第二階段遍曆 整個堆,把清除未標記對象並且把存活對象“壓縮”到堆的其中一塊,按順序排放。此演算法避免了“標記-清除”的片段問題,同時也避免了“複製”演算法的空間問 題。
  5. 增量收集(Incremental Collecting) 
    實施記憶體回收演算法,即:在應用進行的同時進行記憶體回收。不知道什麼原因JDK5.0中的收集器沒有使用這種演算法的。
  6. 分代(Generational Collecting)
    基於對對象生命週期分析後得出的記憶體回收演算法。把對象分為年青代、年老代、持久代,對不同生命週期的對象使用不同的演算法(上述方式中的一個)進行回收。現在的記憶體回收行程(從J2SE1.2開始)都是使用此演算法的。

二、記憶體回收行程


目前的收集器主要有三種:串列收集器、並行收集器、並發收集器 。

  1. 串列收集器 

    使用單線程處理所有記憶體回收工作,因為無需多線程互動,所以效率比較高。但是,也無法使用多處理器的優勢,所以此收集器適合單一處理器機器。當然,此收集器也可以用在小資料量(100M 左右)情況下的多處理器機器上。可以使用-XX:+UseSerialGC 開啟。

  2. 並行收集器
    1. 對年輕代進行並行記憶體回收,因此可以減少記憶體回收時間。一般在多線程多處理器機器上使用。使用-XX:+UseParallelGC .開啟。並行收集器在J2SE5.0第六6更新上引入,在Java SE6.0中進行了增強--可以堆年老代進行並行收集。如果年老代不使用並發收集的話,是使用單線程進行記憶體回收 ,因此會制約擴充能力。使用-XX:+UseParallelOldGC 開啟。
    2. 使用-XX:ParallelGCThreads=<N> 設定並行記憶體回收的線程數。此值可以設定與機器處理器數量相等 。
    3. 此收集器可以進行如下配置:
      • 最大記憶體回收暫停: 指定記憶體回收時的最長暫停時間,通過-XX:MaxGCPauseMillis=<N> 指定。<N>為毫秒.如果指定了此值的話,堆大小和記憶體回收相關參數會進行調整以達到指定值 。設定此值可能會減少應用的輸送量。
      • 輸送量: 輸送量為記憶體回收時間與非記憶體回收時間的比值 ,通過-XX:GCTimeRatio=<N> 來設定,公式為1/(1+N) 。例如,-XX:GCTimeRatio=19時,表示5%的時間用於記憶體回收。預設情況為99,即1%的時間用於記憶體回收。
  3. 並發收集器
    可以保證大部分工作都並發進行(應用不停止),記憶體回收只暫停很少的時間,此收集器適合對回應時間要求比較高的中、大規模應用。使用-XX:+UseConcMarkSweepGC 開啟。
    1. 並發收集器主要減少年老代的暫停時間,他在應用不停止的情況下使用獨立的記憶體回收線程,跟蹤可達對象。在每個年老代記憶體回收周期 中,在收集初期並發收集器會對整個應用進行簡短的暫停,在收集中還會再暫停一次。第二次暫停會比第一次稍長,在此過程中多個線程同時進行記憶體回收工作。
    2. 並發收集器使用處理器換來短暫的停頓時間 。在一個N個處理器的系統上,並發收集部分使用K/N 個可用處理器進行回收,一般情況下1<=K<=N/4 。
    3. 在只有一個處理器的主機上使用並發收集器 ,設定為incremental mode 模式也可獲得較短的停頓時間。
    4. 浮動垃圾 :由於在應用啟動並執行同時進行記憶體回收,所以有些垃圾可能在記憶體回收進行完成時產生,這樣就造成了“Floating Garbage”,這些垃圾需要在下次記憶體回收周期時才能回收掉。所以,並發收集器一般需要20% 的預留空間用於這些浮動垃圾。
    5. Concurrent Mode Failure :並發收集器在應用運行時進行收集,所以需要保證堆在記憶體回收的這段時間有足夠的空間供程式使用,否則,記憶體回收還未完成,堆空間先滿了。這種情況下將會發生“併發模式失敗”,此時整個應用將會暫停,進行記憶體回收。
    6. 啟動並發收集器 :因為並發收集在應用運行時進行收集,所以必須保證收集完成之前有足夠的記憶體空間供程式使用,否則會出現“Concurrent Mode Failure”。通過設定-XX:CMSInitiatingOccupancyFraction=<N> 指定還有多少剩餘堆時開始執行並發收集
  4. 小結
    • 串列處理器: 
      --適用情況:資料量比較小(100M左右);單一處理器下並且對回應時間無要求的應用。
      --缺點:只能用於小型應用
    • 平行處理器: 
      --適用情況:“對輸送量有高要求”,多CPU、對應用回應時間無要求的中、大型應用。舉例:幕後處理、科學計算。
      --缺點:應用回應時間可能較長
    • 並發處理器:
      --適用情況:“對回應時間有高要求”,多CPU、對應用回應時間有較高要求的中、大型應用。舉例:Web伺服器/應用伺服器、電信交換、整合式開發環境。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.