一、垃圾回收算法:
- 引用計數
- 復制算法
- 標記-清除
- 標記-整理
二、垃圾回收的方式:
串行(Serial)、並行(Parallel)、並發(CMS)、G1
1、串行垃圾回收器(Serial)
- 它為單線程環境設計且只使用一個線程進行垃圾回收,會暫停所有的用戶線程,所以不適合服務器環境。
2、並行垃圾回收器(Parallel)
- 多個垃圾收集線程並行工作,此時用戶線程是暫停的,用於科學計算、大數據處理等弱交互場景。
3、並發垃圾回收器(CMS)
- 用戶線程和垃圾收集線程同時執行(不一定是並行,可能是交替執行),不需要停頓用戶線程,互聯網公司多用它,適用對相應時間有要求的場景。
4、G1 垃圾回收器
- G1 垃圾回收器將堆內存分割成不同的區域然后並發的對其進行垃圾回收。
三、如何查看默認的垃圾收集器是哪一個?
java -XX:+PrintCommandLineFlags -version
四、默認的垃圾收集器有哪些?
UseSerialGC,UseParallelGC,UseConcMarkSweepGC,UseParNewGC,UseParallelOldGC,UseG1G
五、垃圾收集器
Java 8 以后基本不使用 Serial Old
配置新生代收集器,老年代收集器會自動配置上
- 新生代
- 串行 GC (Serial)
- 並行 GC (ParNew):配置-XX:+UseParNewGC,新生代並行,老年代串行
- 並行回收 GC (Parallel Scavenge):
串行收集器在新生代和老年代的並行化,配置-XX:+UseParallelGC,新生代、老年代都是並行
可控的吞吐量
自適應調節策略
- 老年代
- 串行 GC (Serial Old)
- 並行 GC (Parallel Old)
- 並發標記清除 GC (CMS)
- 優點:並發收集停頓低
- 缺點:並發執行對 CPU 資源壓力大,采用的標記清除算法會導致大量碎片
配置參數 | 新生代垃圾收集器 | 新生代垃圾收集算法 | 老年代垃圾收集器 | 老年代垃圾收集算法 |
-XX:+UseSerialGC | Serial | 復制算法 | Serial Old | 標記-整理算法 |
-XX:+UseParNewGC | ParNew | 復制算法 | Serial Old | 標記-整理算法 |
-XX:+UseParallelGC | Parallel Scavenge | 復制算法 | Parallel Old | 標記-整理算法 |
-XX:+UseParalleOldlGC | Parallel Scavenge | 復制算法 | Parallel Old | 標記-整理算法 |
-XX:+UseConcMarkSweepGC | ParNew | 復制算法 | CMS+Serial Old | 標記-清除算法 |
-XX:+UseG1GC | G1整體上采用標記-整理算法 | 局部是通過復制算法,不會產生內存碎片 |
代碼驗證:
/** * 1、-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialGC (DefNew+Tenured) * * 2、-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC (ParNew+Tenured)java8不再被推薦 * Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector * is deprecated and will likely be removed in a future release * * 3、-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC (PSYoungGen+ParOldGen) * * 4、-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelOldGC (PSYoungGen+ParOldGen) * * 5、-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC (ParNew+CMS) * * 初始標記:CMS Initial Mark * 並發標記(和用戶線程一起):CMS-concurrent-mark * 重新標記:CMS Final Remark * 並發清除(和用戶線程一起):CMS-concurrent-sweep */ public class GCoverheadDemo { public static void main(String[] args) { int i = 0; List<String> list = new ArrayList<>(); while (true) { list.add(String.valueOf(++i).intern()); } } }
六、如何選擇垃圾收集器?
- 單 CPU 或者小內存,單機程序:-XX:UseSerialGC
- 多 CPU 需要最大吞吐量,如后台計算型應用:-XX:UseParallelGC 或者 -XX:UseParallelOldGC
- 多 CPU 追求低停頓時間,需要快速響應,如互聯網應用:-XX:+UseConcMarkSweepGC