JVM基础总结04 - JVM进阶之垃圾回收
一、GC垃圾回收算法和垃圾收集器的关系?分别是什么
1.GC算法(引用计数/复制/标记清楚/标记整理)是内存回收的方法论,垃圾收集器是算法的落地实现
2.目前为止还没有完美的收集器出现,更没有万能的收集器,只有针对具体应用最合适的收集器,进行分代收集
二、4种主要的垃圾收集器
串行 并行 并发 G1
1.串行垃圾回收器
它为单线程环境设计,且只使用一个线程进行垃圾回收,会暂停所有的用户线程,所以不适合服务器环境
2.并行垃圾回收器
多个垃圾收集线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景
3.并发垃圾回收器concurrent mark sweep
用户线程和垃圾收集线程同时执行(不一定并行,可能交替执行)不需要停顿用户线程。互联网公司多用,适用对响应时间有要求的场景
4.G1
G1垃圾回收器将堆内存分割成不同的区域然后并发地对其进行垃圾回收
三、查看服务器默认的垃圾收集器
1.怎么查看默认的垃圾收集器是哪个?
2.默认的垃圾收集器有哪些?
UseSerialOldGC已淘汰
四、生产上如何配置垃圾收集器?谈谈你对垃圾收集器的理解
1.垃圾收集器组合
2.部分参数说明
DefNew:Default New Generation
Tenured:Old
ParNew:Parallel New Generation
PSYoungGen:Parallel Scavenge
ParOldGen:Parallel Old Generation
3.Server/Client模式分别是什么意思
4.新生代收集器
4-1.串行GC(Serial)/(Serial Copying)
4-2.并行GC(ParNew)
4-3.并行回收GC(Parallel)/(Parallel Scavenge)
5.老年代收集器
5-1.串行GC(Serial Old)/(Serial MSC)
5-2.并行GC(Parallel Old)/(Parallel MSC)
5-3.并发标记清楚GC(CMS) CMS 使用标记清除算法,节约空间但产生内存碎片
并发标记清除4步过程:
- 初始标记(CMS initial mark):只是标记一下GCRoots能关联的对象,速度很快,需要STW
- 并发标记(CMS concurrent mark)和用户线程一起:进行GCRoots跟踪的过程,标记所有对象
- 重新标记(CMS remark):修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,需要STW
- 并发清除(CMS concurrent sweep)和用户线程一起
由于耗时最长的并发标记和并发清除,垃圾回收线程能和用户线程一起工作,所以总体看来CMS收集器的内存回收和用户线程是一起并发执行的
CMS收集器的优缺点:
优点:并发收集停顿低
缺点:并发执行,对CPU压力较大,CMS需要在老年代堆内存耗尽前完成垃圾回收,否则CMS回收失败时会触发担保机制,串行老年代收集器将会以一次STW的方式进行GC,从而造成较大的停顿时间;
采用的标记清除算法会产生大量碎片:CMS提供了参数-XX:CMSFullGCsBeForeComPaction来指定对少次CMS收集之后进行一次压缩FullGC,默认是0,即每次CMS收集后都会进行压缩FullGC
6.垃圾收集器配置代码总结
底层代码:
实际代码:
1.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialGC
2.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC
3.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC
4.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelOldGC
5.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC
6.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseG1GC
7.-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialOldGC 已经没有了
7.如何选择垃圾收集器?
五、G1收集器
1.以前收集器特点
- 年轻代和老年代是各自独立且连续的内存块
- 年轻代收集,使用单eden+S0+S1进行复制算法
- 老年代收集必须扫描整个老年代区域
- 都是以尽可能快速地执行GC为设计原则
2.G1收集器是什么?
3.G1收集器是的特点
小区域的收集+形成连续的内存块
4.G1底层原理
- Region区域化垃圾收集器,最大的好处是化整为零,避免全内存扫描,只需要按区域来进行扫描即可
- 回收步骤
- 4步回收过程
5.代码示例
public class GCDemo {
public static void main(String[] args) {
System.out.println("GCDemo...");
try {
String str = "bjtu";
while (true) {
str += str + new Random().nextInt(77777777) + new Random().nextInt(88888888);
str.intern();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseG1GC
6.常用配置参数
-XX:UseG1GC
-XX:G1HeapRegionSize=n:设置区域的大小,值是2的幂,范围是1~32M,共2048块
-XX:MaxGCPauseMillis=n:最大GC停顿时间,软目标,JVM尽可能但不保证,停顿小于这个时间
-XX:InitialHeapOccupancyPercent=n 堆占用多少时就出发GC,默认值为45,即45%
-XX:ConcGCThreads=n 并发GC使用的线程数
-XX:G1ReversePercent=n 设置作为空闲空间的预留内存百分比,默认10%,以减少目标空间溢出的风险
7.G1和CMS相比的优势
比起cms有两个优势:
1)G1不会产生内存碎片
2)可以精确控制停顿。该收集器把整个堆(新生代、老生代)划分为多个固定大小的区域,每次根据允许停顿的时间去收集垃圾最多的区域。