垃圾收集算法、垃圾回收算法、java垃圾收集器

垃圾收集算法、垃圾回收算法、java垃圾收集器

目錄
1. 垃圾收集算法
1)引用計數法
2)根搜索法
2. 垃圾回收算法
1)複製算法
2)標記-清除算法
3)標記-整理算法
4)分代收集算法
3. java垃圾收集器
新生代GC器:
1)Serial垃圾收集器
2)ParNew垃圾收集器
3)Parallel Scavenge垃圾收集器
老年代GC器
1)Serial和Parallel Scavenge都有對應的老年代版本
2)CMS垃圾收集器
G1回收器
4.java對象的內存分配位置
5.java TLAB
6.java 何時觸發GC
1) new gen對象什麼時候會晉升到old gen中?
2) 什麼時候會出現old gen空間不足(old gen空間不足時,會觸發full gc)?

  1. 垃圾收集算法

1)引用計數法

     給對象添加引用計數器,當引用對象時計數器+1,引用失效時,計數器-1,當計數器等於0時,對象失效,內存可以被回收。

優點:實現簡單高效。

缺點:對象之間的互相循環引用問題不好解決。

2)根搜索法

     通過GC roots可達的對象路徑稱爲引用鏈(reference chain),當一個對象沒有引用鏈時(即從GC roots不可達)則視爲不可用對象,內存可以被回收。java使用該算法進行垃圾收集。

哪些對象可以視爲GC roots ?

a. 虛擬機棧中(即棧幀中的本地變量)的引用對象;

b. 本地方法棧中的引用對象;

c. 方法區(永久代)中的靜態變量引用的對象和常量池中引用的對象

  1. 垃圾回收算法

1)複製算法

     將內存分爲(大小相等)兩部分,每次只使用其中一塊進行內存分配,當內存使用完後,就出發GC,將存活的對象直接複製到另一塊空閒的內存中,然後對當前使用的內存塊一次性清除所有,然後轉到另一塊內存進行使用。

優點:簡單,高效。

缺點:浪費內存,因爲每次都有另一塊內存空閒着。

2)標記-清除算法

     分兩步進行,第一步標記出可以回收的對象,第二步統一清理可以回收的對象內存。

缺點:首先標記和清除步驟效率都不高,其次會產生內存碎片。

3)標記-整理算法

     類似於標記-清除算法,但是第二步進行內存回收時,將存活的對象向內存一端移動,達到消除內存碎片問題。

4)分代收集算法

     java sun hotspot虛擬機將內存分爲新生代(堆)、老年代(堆)、永久代(方法區、常量池、即時編譯代碼)幾個區域,新生代主要使用基於複製算法的垃圾回收,老年代和永久代主要使用標記-整理算法進行垃圾回收。具體每個區域使用哪種垃圾回收算法還要視收集器的實現制約。

這裏寫圖片描述

  1. java垃圾收集器

新生代GC器:

1)Serial垃圾收集器:

     單線程串行垃圾收集器,使用複製算法進行垃圾回收,GC時需要暫停所有用戶線程,直到GC完成。

注:此處的串行垃圾收集器中的串行意義是指GC過程和用戶線程執行過程是串行的,即GC過程中用戶線程暫停,用戶線程執行是,GC是不執行的。

2)ParNew垃圾收集器:

     多線程串行垃圾收集器,Serial的多線程版本,其它特性同Serial。

3)Parallel Scavenge垃圾收集器:

     類似於ParNew,但是該收集器關注的是cpu的吞吐量(throughput=user-cpu-time/total-cpu),通過參數-XX:GCTimeRation和-XX:MaxGCPauseMillis來控制吞吐量,是吞吐量優先的收集器,同樣使用複製算法進行垃圾回收,GC過程需要暫停所有用戶線程。

老年代GC器:

1)Serial和Parallel Scavenge都有對應的老年代版本:

     Serial Old和Parallel Old垃圾收集器,它們與新生代的區別在於老年代區域的版本,採用標記-整理算法進行垃圾回收。

2)CMS垃圾收集器:

     Concurrent Mark Sweep收集器,是真正意義上的多線程並行垃圾收集器,CMS在GC過程中的某些階段用戶線程是可以運行的,因此說它是真正意義上的並行垃圾收集器,前面介紹的垃圾收集器在GC過程中都要暫停用戶線程,因此,視它們爲與用戶線程串行執行的垃圾收集器。CMS GC過程分四步完成:

a.初始標記:只是標記一下GC Roots能直接關聯的對象,速度很快,仍然需要暫停所有的工作線程。

b.併發標記:進行GC Roots跟蹤的過程,和用戶線程一起工作,不需要暫停工作線程。

c.重新標記:爲了修正在併發標記期間,因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄,仍然需要暫停所有的工作線程。

d.併發清除:清除GC Roots不可達對象,和用戶線程一起工作,不需要暫停工作線程。

**G1回收器:

參考:http://www.importnew.com/15311.html

  1. java對象的內存分配位置

1) 編譯器通過逃逸分析,確定對象是在棧上分配還是在堆上分配。如果是在堆上分配,則進入選項2.
2) 如果tlab_top + size <= tlab_end,則在在TLAB上直接分配對象並增加tlab_top 的值,如果現有的TLAB不足以存放當前對象則3.
3) 重新申請一個TLAB,並再次嘗試存放當前對象。如果放不下,則4.
4) 在Eden區加鎖(這個區是多線程共享的),如果eden_top + size <= eden_end則將對象存放在Eden區,增加eden_top 的值,如果Eden區不足以存放,則5.
執行一次Young GC(minor collection)。
5) 經過Young GC之後,如果Eden區任然不足以存放當前對象,則直接分配到老年代。

  1. java TLAB
    JVM在內存新生代Eden Space中開闢了一小塊線程私有的區域,稱作TLAB(Thread-local allocation buffer)。默認設定爲佔用Eden Space的1%。在Java程序中很多對象都是小對象且用過即丟,它們不存在線程共享也適合被快速GC,所以對於小對象通常JVM會優先分配在TLAB上,並且TLAB上的分配由於是線程私有所以沒有鎖開銷。因此在實踐中分配多個小對象的效率通常比分配一個大對象的效率要高。
    也就是說,Java中每個線程都會有自己的緩衝區稱作TLAB(Thread-local allocation buffer),每個TLAB都只有一個線程可以操作,TLAB結合bump-the-pointer技術可以實現快速的對象分配,而不需要任何的鎖進行同步,也就是說,在對象分配的時候不用鎖住整個堆,而只需要在自己的緩衝區分配即可。
    關於對象分配的JDK源碼可以參見JVM 之 Java對象創建[初始化]中對OpenJDK源碼的分析。

  2. java 何時觸發GC

eden或old gen空間不足時會發出minor gc或full gc。

1) new gen對象什麼時候會晉升到old gen中?

  1. 多次minor gc後依然存活的對象,在存活年齡超過MaxTenuringThreshold閾值時會晉升到old gen中。
  2. 在創建大對象/數組時,如果設置了PretenureSizeThreshold,超過大小的對象會直接在old gen中分配內存。

2) 什麼時候會出現old gen空間不足(old gen空間不足時,會觸發full gc)?
1. 創建大對象,大數組時,如果設置了PretenureSizeThreshold,超過閾值會直接在old gen中分配內存,此時可能會出現old gen內存不足。
2. minor gc完成後,可能會有對象滿足了MaxTenuringThreshold設置的晉升年齡,需要晉升到old gen,此時可能會出現old gen內存不足。
3. 如果設置了新生代收集擔保機制即HandlePromotionFailure關閉,則會在old gen中預留edu+survivor大小的空間作爲擔保,如果minor gc時,
old gen無法提供足夠內存進行擔保,會出現old gen內存不足。
4. 調用System.gc()時,會建議jvm進行full gc,但是並不保證一定會進行,大多數情況會執行full gc。因此,要慎用System.gc(),因爲full gc
比較耗時,增加full gc次數會嚴重影響程序執行效率。-XX:+DisableExplicitGC可以關閉System.gc()調用。
5. perm gen內存不足時,也會出發full gc。

參考:

垃圾收集算法和垃圾回收算法:

http://www.2cto.com/kf/201401/272681.html

java垃圾收集器:

http://blog.csdn.net/chjttony/article/details/7883748 (推薦)

http://www.cnblogs.com/wrencai/articles/4232264.html

內存模型:

http://www.cnblogs.com/wrencai/articles/4232264.html

java對象都是分配在堆上嗎:

http://blog.hesey.net/2011/07/object-allocation-on-non-heap.html

java逃逸分析和對象內存分配,TLAB:

http://blog.csdn.net/yangzl2008/article/details/43202969

java虛擬機參數:

http://java.9sssd.com/jvm/art/432

http://www.tuicool.com/articles/RNjUfa

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章