GC是啥?
GC垃圾回收:java語言的特點之一,不需要開發人員關心內存資源的釋放,但是會增加軟件系統的負擔,算是有利有弊吧,但是選擇合適的GC就會很明顯利大於弊了。
- 先大致瞭解一下JVM內存區域:
JVM內存模型:
注意:
1.java8之後取消永久帶,設置了元空間(不佔用虛擬機內存,而是機器本地內存),常量池被放到了方法區。
2.私有內存伴隨着線程的產生而產生,一旦線程終止,私有內存區也會自動消除,所以垃圾回收不在此探討範圍內,着重看一下堆內存。
堆內存:
概念:所有的對象實例都要在堆上分配,無論死的還是活的對象。
作用:動態申請分配一定大小的內存空間
模型:
負責GC的垃圾回收器常用算法
垃圾回收算法概述:
1.複製算法:
根節點掃描所有存活對象複製到新內存中,將原來那塊內存回收掉。
----適合新生代
2.標記-清除算法:
兩個階段,標記階段和清除階段,從根節點開始,未標記的就是未被引用的垃圾對象,清除階段清除所有未被標記的對象。
3.標記-壓縮算法:
在標記-清除的基礎上優化,一輪掃描後,先將所有存貨對象壓縮到內存另一端,之後清理邊界外所有空間,可規避碎片的產生。
4.代回收算法:
不同年代使用不同算法,選擇最合適的。新生代存活率低,可以用複製算法,而老年代存活率高,沒有額外空間分配擔保,用標記清除或者標記整理(壓縮)。
新生代GC:
Minor GC垃圾回收,eden中存活對象會複製到未被使用的sur0中,正在使用的sur1的年輕對象也會被複制到sur0中(大、老對象進入老年代),如果sur0已滿,對象也直接進入老年代,此時eden中和sur1的剩餘對象就是垃圾對象,直接清空,而sur0中就是此次回收存活的所有對象,複製算法保證了內存的連續性,也避免了內存空間的浪費。最後sur0和sur1互換,保持sur0爲空,如此反覆,如果複製對象達到16次,那麼這個對象就可以送去老年代了。
特點:頻率高、速度快
Survivor的存在意義:減少被送到老年代的對象,進而減少Full GC的發生,Survivor的預篩選保證,只有經歷16次Minor GC還能在新生代中存活的對象,纔會被送到老年代。保證永遠有一個survivor space是空的,另一個非空的survivor space無碎片。
老年代GC:
Major GC:經歷16次的還存活就被送到老年代,老年代空間一般較大,使用標記-清除
算法。掃描後回收,會產生內存碎片。標記-壓縮算法可規避。特點:是頻率低速度慢也就是當老年代也放不下的時候發生FullGC,耗時嚴重。System.gc()也會發生。
垃圾回收器
分類:
1.使用串行回收器的相關參數:
-XX:+PrintGCDetails:打印GC信息。
-XX:+UseSerialGC:新生代、老年代都使用串行回收器。
-XX:+UseParNewGC :新生代使用並行收集器,老年代使用串行收集器。
2.使用並行回收器的相關參數:
-XX:+UseParNewGC:新生代使用並行收集器,老年代使用串行收集器。
-XX:ParallelGCThreads :並行收集器工作時的線程數量。
-XX:+UseParallelGC:新生代使用並行回收收集器,老年代使用串行收集器。
-XX:+UseParallelOldGC:新生代和老年代都是用並行回收收集器。
-XX:+MaxGCPauseMills:設置最大垃圾收集停頓時間,它的值是一個大於 0 的整數。
-XX:+GCTimeRatio:設置吞吐量大小,它的值是一個 0-100 之間的整數。假設 GCTimeRatio 的值爲 n,那麼系統將花費不超過 1/(1+n) 的時間用於垃圾收集。
3.使用CMS回收器相關參數:
-XX:+UseConcMarkSweepGC: 新生代使用並行收集器,老年代使用 CMS+串行收集器。
-XX:CMSInitiatingOccupancyFraction:指定回收閾值,默認是 68。
-XX:+UseCMSCompactAtFullCollection: CMS 在垃圾收集完成後,進行一次內存碎片整理。內存碎片的整理並不是併發進行的。
-XX:CMSFullGCsBeforeCompaction:設定進行多少次 CMS 回收後,進行一次內存壓縮。
4.使用G1回收器相關參數:
-XX:+UnlockExperimentalVMOptions:允許使用實驗性參數。
–XX:+UseG1GC:啓用 G1 回收器.
-XX:MaxGCPauseMills:設置 G1 回收器的最大停頓時間。
-XX:GCPauseIntervalMills:設置 G1 回收器的目標停頓時間間隔。
參數參考:JVM 垃圾回收器工作原理及使用實例介紹
相信讀完本文,對於GC的概念應該就不會那麼陌生了~