jvm垃圾回收算法

面试的时候有个问题很容易被问到,就是垃圾回收算法有哪几个,并且讲一下各自的原理,其实就只有4个,很简单,话不多说,直接开始:

1.标记清除算法
2. 复制算法
3. 标记压缩算法
4. 分代算法

标记清除算法

分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有 被标记的对象,它的标记过程其实在前一节讲述对象标记判定时已经介绍过了。之所以说它 是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到 的。
它的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是 空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程 序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾 收集动作。
我用自己的话总结一下:
标记清除算法的优点和缺点

  1. 优点
  • 是可以解决循环引用的问题
  • 必要时才回收(内存不足时)
  1. 缺点:
  • 回收时,应用需要挂起,也就是stop the world。
  • 标记和清除的效率不高,尤其是要扫描的对象比较多的时候
  • 会造成内存碎片(会导致明明有内存空间,但是由于不连续,申请稍微大一些的对象无法做到)
  • 应用场景是(老年代,老年代需要GC少,所以比较适用)
复制算法

将可用内存按容 量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着 的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是 对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指 针,按顺序分配内存即可,实现简单,运行高效。只是这种算法的代价是将内存缩小为了原 来的一半,未免太高了一点。
将内存 分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor[1]。 当回收时,将Eden和Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最 后清理掉Eden和刚才用过的Survivor空间。
我用自己的话总结一下:
如果jvm使用了复制算法,一开始就会将可用内存分为两块,from域和to域(s0和s1), 每次只是使用from域,to域则空闲着。当from域内存不够了,开始执行GC操作,这个时候,会把from域存活的对象拷贝到to域,然后直接把from域进行内存清理.
大致步骤如下:
1、当Eden区满的时候,会触发第一次young gc,把还活着的对象拷贝到Survivor From区;当Eden区再次触发young gc的时候,会扫描Eden区和From区域,对两个区域进行垃圾回收,经过这次回收后还存活的对象,则直接复制到To区域,并将Eden和From区域清空。
2、当后续Eden又发生young gc的时候,会对Eden和To区域进行垃圾回收,存活的对象复制到From区域,并将Eden和To区域清空。
3、可见部分对象会在From和To区域中复制来复制去,如此交换15次(由JVM参数MaxTenuringThreshold决定,这个参数默认是15),最终如果还是存活,就存入到老年代
所以说s0和s1有一个一定时空的,就是为了方便下次的复制。

  1. 优点
  • 解决了碎片化问题
  • 能够快速清理干净
  1. 缺点:
  • 在对象存活率比较高的地方,就会进行很多的复制操作,效率低
    - 应用场景是(新生代,新生代存活率比较低,基本上是招生夕死,很快)
标记压缩算法

“标记-整理”(Mark-Compact)算法,标记过程 仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存 活的对象都向一端移动,然后直接清理掉端边界以外的内存。
这个好理解,就是先标记,然后把没有引用的对象移动到一端,直接GC那部分内存。

优点:解决内存碎片问题
缺点:压缩阶段,由于移动了可用对象,需要去更新引用。(速度慢)
应用场景:老年代(老年代的存活率比较高)

分代算法

当前商业虚拟机的垃圾收集都采用“分代收集”(Generational Collection)算法,这种算 法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把Java堆 分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代 中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付 出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间 对它进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法来进行回收。
这个算法就是综合了上面几种的优点,让每个算法都能发挥自己的特点。

MinorGC 和MajorGC(FullGC)的区别

新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝 生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴 随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行 Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。
所以说新生代是minorGC ,老年代是MajorGC, FullGC是对堆里所有内存都进行回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值