Java垃圾回收-回收算法

回收算法

标记清除算法(Mark and Sweep)
标记:从根集合进行扫描,对存活的对象进行标记。
清除:对堆内存从头到尾进行线性遍历,回收不可达对象内存。将原来标记为可达的对象标识清除,一遍进行下一次垃圾回收
在这里插入图片描述
缺点:由于标记清除不需要对象的移动,并且只对不存活的对象进行处理。因此,标记清除过后,会产生大量的内存碎片,空间碎片太多,需要分配较大的对象时,无法找到连续的内存,而不得不提前触发另一次垃圾收集工作。

复制算法(Copying)

  • 分为对象面和空闲面。将可用内存按容量,按一定比例划分为两块或多个块,并选择其中一块或者两块作为对象面,其他的作为空闲面。
  • 对象在对象面上创建
  • 如果属于对象面的块内存用完,将还存活的对象复制到其中一块空闲面上
  • 将对象面所有对象内存清除
    这种算法适用于对象存活率低的场景,比如年轻代。这样每次都对整个区域进行内存回收,内存分配时,也就不用考虑内存碎片等复杂情况。推倒重建只需要移动那个堆顶指针,按顺序分配内容即可。实现简单,运行高效。
    在这里插入图片描述
    标记-整理算法(Compacting)
    对于老年代,复制回收算法就力不从心了。对象块中的对象存活率高,复制的效率变低。如果不想浪费50%的空间,就需要有额外的空间进行担保,以应对所有对象都存活的极端情况。而标记-整理算法比较适合老年代
    标记:从根集合进行扫描,对存活的对象进行标记。
    清除:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。
    在这里插入图片描述
  • 避免了内存的不连续性
  • 不用设置两块内存互换
  • 适用于对象存活率高的场景

分代收集算法(Generational Collector)

  • 垃圾回收算法的组合
  • 按照对象的生命周期的不同划分区域以采用不同的垃圾回收算法

在这里插入图片描述
在这里插入图片描述

分代收集的GC分类

年轻代

发生在年轻代的垃圾收集工作,采用的是复制算法。年轻代几乎是所有java对象出生的地方。即java申请的内存和存放,都是在这个地方进行,大部分对象不需要长久地存活,具有朝生夕灭的性质。当一个对象被判定为死亡的时候,GC有责任回收掉这一部分对象的内存空间。新生代是垃圾回收的频繁区域。

Minor GC
尽可能快速的收集掉那些生命周期短的对象
Eden区,两个Survivor区(from和to)
在这里插入图片描述
演示:
在这里插入图片描述
此时Eden填满,将存活对象填入S0,S0就是from区,清理Eden区,存活对象的年龄增加1。
在这里插入图片描述
此时Eden区又被填满,又触发Minor GC,将Eden区和S0存活的对象放入S1,年龄在本身的基础上加1,清空Eden和S0
在这里插入图片描述
此时Eden区又满了,触发第三次Minor GC 将S1和Eden的存活对象转移到S0,年龄增加1,清空S1和Eden
当对象的年龄达到某个值,就会被存入老年代,默认为15,可以通过-XX:MaxTenuringThreshold进行调整。如果对象较大,Eden和Survivor装不下,则直接被存入老年代。
对象如何晋升到老年代

  • 经过一定Minor次数仍然存活的对象
  • survivor区存放不下的对象
  • 新生成的大对象(-XX:PretenuerSizeThreshold

常用调优参数
在这里插入图片描述

老年代

Full GC

Full GC比Minor GC慢,但执行频率低

触发Full GC的条件

  • 老年代空间不足
  • 永久代空间不足(jdk7及以前版本出现)
  • CMS GC时出现promotion failed,concurrent mode failure
  • Minor GC晋升到老年代的平均大小大于老年代的剩余空间
  • 调用System.gc()
  • 使用RMI来进行或管理的JDK应用,每小时执行一次Full GC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值