1.哪些對象可以被回收-根搜索算法。
2.可作爲GC roots的對象有:
a.虛擬機棧幀中引用的對象
b.方法區中的類靜態變量屬性引用點對象
c.方法區中的常量引用的對象
d.本地方法棧中的JNI(native方法)的引用對象
3.永久代的垃圾收集:廢棄常量和無用的類
廢棄常量的收集:判斷有木有對象引用它,沒有就回收。
無用的類的收集需滿足以下三個條件:a.不存在該類的任何實例;b.加載該類的classloader已經被回收;c.該類對應的java.lang.Class對象沒有在任何地方被引用,無法通過反射訪問該類的方法。
參數
-Xnoclassgc控制回不回收類
-verbose:class -XX:+TraceClassLoading,-XX:+TraceClassUnLoading查看類的加載和卸載信息
4.垃圾收集算法
標記-清除算法(最基礎的算法):先標記要清除的對象,然後清除。
缺點:標記和清除兩個階段的效率不高,且容易產生內存碎片,碎片過多會導致無法找到一個連續的足夠大的內存空間來分配,進而會提前觸發下一次垃圾收集。
複製算法(適用於新生代,因爲新生代一般來說存活的對象很少,所以需要複製的對象就少):將新生代分爲3個區:1個eden,2個survivor。每次收集時將eden和一個survivor中存活的對象複製到另一個survivor,然後將前者清除。當後者的空間不足以保存所有活着的對象,可以用老年代來做分配擔保(Handle Promotion)。
複製算法會浪費一個survivor的空間,且需要老年代作擔保。而老年代自己本身沒有誰擔保,所以不能採用該算法
標記-整理算法(適用於老年代,因爲老年代存活對象較多,且該算法不會像複製算法那樣浪費空間):先標記,然後將存活的對象向一端移動,清理掉端外的空間。
分代收集算法:將java堆分爲新生代和老年代,不同的代採用不同的算法。
5.垃圾收集器
Serial收集器:複製算法,stop the world.
一般作爲client模式下新生代的默認收集器。
-XX:SurvivorRatio eden和survivor的分配比例
-XX:PretenureSizeThreshold 直接晉升老年代的對象大小
-XX:MaxTenuringThreshold晉升老年代對象年齡
-XX:HandlePromotionFailure 是否開啓分配擔保
ParNew收集器:複製算法,serial收集器的多線程版本,同樣需要stop the world.
一般作爲server模式下新生代的默認收集器。---目前只有它和serial能與CMS收集器配合工作。
-XX:ParallelGCThreads 控制垃圾收集的線程數
Parallel Scavenge收集器:新生代,複製算法,多線程,關注吞吐率(提高cpu的利用率),適合於後臺運算而不需要太多交互任務的程序。
-XX:MaxGCPauseMillis控制最大垃圾收集停頓時間
-XX:GCTimeRation 控制吞吐率
上面兩個參數的關係:若要想獲取低停頓,必然導致低;若想獲取高吞吐,必然導致每次停頓延長。
-XX:UseAdaptiveSizePolicy 自適應調節新生代大小,eden和survivor的比例,晉升老年代對象年齡等細節參數。
Serial Old收集器:老年代,標記-整理算法,
client模式默認老年代的收集器。
server模式下,兩大用途:一是1.5及之前與Paraller Scavenge搭配使用。二是作爲CMS收集器的後備預案,當發生Concurrent Mode Failure的時候使用。
Parallel Old收集器:Parallel Scavenge收集器的老年代版本,標記-整理算法。1.6開始提供(所以1.5之前paraller scavenge只能與serial old搭配使用)。
Parallel Scavenge/Paraller Old搭配使用,提供高吞吐率的組合。
CMS收集器:(concurrent mark sweep,併發標記清除),老年代,關注最短停頓時間,重視響應速度。應用於互聯網站或B/S系統的服務端。
過程:初始標記(stop the world,僅僅標記gc roots直接關聯到的對象,速度很快),併發標記(gc roots tracing),重新標記(stop the world,修正併發標記期間程序運行導致標記產生變動的那一部分對象),併發清除。
CMS無法處理浮動垃圾(在併發清理階段,可能還會產生一部分垃圾,這部分垃圾只能在下一次清除)。即清理之前必須預留一定的空間來爲用戶線程運行做準備。默認情況,當老年代空間佔用達到68%就觸發CMS收集器收集。若預留的空間無法滿足程序運行的需求,就會出現Concurrent Mode Failure.此時啓用後備方案Serial Old重新進行老年代的收集。
由於採用標記清除算法,易產生內存碎片。
-XX:+UseCMSCompactAtFullCollection參數來控制是否在一次FullGC之後來一次碎片整理過程(need stop the world).
-XX:CMSFullGCFullGCsBeforeCompaction執行多少次不壓縮的FullGC之後來一次帶壓縮的。
-XX:CMSInitiatingOccupancyFraction的值來控制空間佔用多少時觸發收集。
G1收集器:標記-整理算法。精確控制停頓時間(實時java的垃圾收集器特徵)。可以在基本不犧牲吞吐率的前提下儘量完成低停頓。將java堆分成多個大小固定的區域,每次選擇垃圾最多的區域進行收集,以獲取最高的收集效率。