JVM垃圾回收机制

1.可达性分析

Java从一系列的GC roots作为头节点,向下遍历,不在其路径(引用链)下的对象就是不可达的。GC roots可以是方法区的类静态属性引用的对象,或是方法区常量的引用对象,以及虚拟机栈和本地方法栈的引用对象。所有的GC roots都存放在一个叫OopMap的数据结构中。

2.JVM的垃圾回收算法

2.1 分代回收算法

与其说是一种算法,它更像是一种思想,它根据对象存活的时间将内存划分为老年代和新生代, 对于两者分别用合适的垃圾回收算法;

2.2 标记清除算法

发生在老年代,标记清除算法会遍历两次,第一次标记需要回收的对象,第二次进行清除,使用后会产生内存碎片;

2.3 复制算法

多在新生代使用的算法,将存活的对象拷贝到另一个空间中,然后直接将原来的空间清空。 这样做执行效率高,还可以避免产生内存碎片。

在实际应用中,由于新生代的对象大多数都会被回收,所以将空间分为一个Eden区(占80%)和两个Survivor区(各占10%), 每次使用一个Eden区和一个Survivor区来储存对象,每次垃圾回收时,将存活的对象拷贝到另一个Survivor区,如果Survivor区的空间不足,会占用老年代的空间;

2.4 标记整理算法

发生在老年代中,会遍历两次,第一次遍历标记将要回收的对象,第二次将存活的对象全部朝一端移动,然后清空边界以外的内存;这种方法使用后不会产生内存碎片。

3.Minor GC和Full GC的触发

Minor GC的触发:

当JVM无法为新的对象分配空间时会触发Minor GC,例如当Eden区和Survivor区满了的时候,默认情况下,新生代的对象在经历15次Minor GC后进入会老年代;

Full GC的触发:

1.调用System.gc()方法会建议系统执行Full GC;

2.当老年代空间不足时会触发Full GC,如果频繁发生Full GC,建议调整新生代和老年代的比例, 让对象尽量在Minor GC阶段被回收,并且尽量不要创建过大的对象,以及让对象在新生区存活的久一点。

3.当方法区空间不足时也会触发Full GC;

4.垃圾回收器

4.1 Serial收集器(不用)

单线程的收集器,在工作时必须停止所有工作线程(stop the world),使用复制算法;

4.2 Serial Old

和Serial一起使用,分别作用于新生代和老年代,使用标记整理算法;

4.3.ParNew

使用多线程进行垃圾回收,在工作时必须停止所有工作线程,和CMS配合使用;

4.4.CMS(并发标记清除)

是一种以获取最短回收停顿时间为目标的收集器,重视服务器的响应速度,希望系统停顿时间虽短,适合堆内存大,CPU核数多的服务器端应用,Serial Old作为CMS出错后的备用收集器。

步骤:初始标记(需要STW),并发标记,重新标记(需要STW),并发清除,初始标记只标记GC Roots可以关联到的对象,并发标记负责对GC Roots进行追踪,标记存活的对象,重新标记负责标记在并发标记过程中标记信息发生变动的对象,并发清除负责回收;

优点:
并发收集停顿低;

缺点:
1.对CPU资源压力大;

2.会产生内存碎片,其默认会在需要时对内存碎片进行合并整理,该过程会STW,用户也可以设置在一定次数的Full GC后执行一次带压缩的Full GC;

3.需要额外预留一部分内存空间给用户,所以当老年代还有一定的空间时就会触发,因为它的垃圾清理是和线程并发进行的,清理的过程中还会产生内存垃圾, 这些垃圾被称为浮动垃圾,如果浮动垃圾过多就会启用serial oid收集器来处理,从而产生较大的停顿;

4.5 Parallel Scavenge(默认使用)

新生代的垃圾回收器,吞吐量优先的垃圾回收器,用户可以自行设置吞吐量的大小和最大垃圾回收时间, 使用多线程进行垃圾回收,使用复制算法收集,和Parallel Old配合使用;

4.6 Parallel Old

老年代的垃圾回收器,使用多线程进行垃圾回收,使用标记整理算法

4.7 G1

不再分新生代和老年代,而是将整体划分成多个子区域,整体上采用标记整理算法,局部上采用复制算法,不会产生内存碎片,STW时间可由用户自己设置。一些区域被划分为老年代,当对这些区域清理时,直接将对象复制到另一个区域,就不会产生内存碎片,其运行阶段大致可分为:初始标记,并发标记(不需要STW),最终标记,筛选整理。 与CMS相比的优势:没有内存碎片,可以控制停顿时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值