JVM垃圾回收策略

判断对象是否存活

  • 引用计数算法: 对象中添加一个计数器,计数器为0则没有引用
    • 优点: 简单 效率高
    • 缺点: 无法解决循环引用的问题
  • 可达性分析算法: 以GC Roots为起点向下搜索,当一个对象到GC Roots没有任何引用链相连,则是不可用的
  • 引用分为 强引用 软引用 弱引用 虚引用四种强度
  • 不可达的对象,经过两次标记,才会真正死亡(finalize方法)
  • 方法区也有回收: 废弃常量 & 无用的类

HotSpot在进行可达性分析,枚举根节点时,会触发Stop The World,停止所有线程


GC算法

  • 标记 - 清除算法: 存在效率问题 & 内存碎片问题
  • 复制算法: 将内存划分为两块大小相等的区域,回收时,把存活的对象复制到另外一块
    • 高效 but 内存缩小了一半
    • 采用此算法回收新生代,一块较大的Eden区和两块较小的Survivor区: 将Eden和Survivor活着的对象一次性复制到另外一个Survivor区
    • HotSpot默认Eden和Survivor大小8:1
    • Survivor不够用时 需要老年代空间进行内存分配担保
  • 标记 - 整理算法: 标记后不对可回收对象进行清除,而是让活着的对象向一段移动,然后直接清理掉边界以外的内存

新生代只有少量对象存活,选用复制算法;老年代对象存活率高,选用标记-清除/整理算法回收

HotSpot在GC发生时,采用主动式中断,在线程的安全区域发起GC

  • 安全点 : 以是否具有让程序长时间执行的特征来选定
    • 主动式中断: 设置中断标志,各个线程轮询这个标志,并把自己挂起
    • 抢断式中断: 首先把所有线程中断,检测不在安全点的线程,恢复跑到安全点
  • 安全区 : 一段代码片段中,引用关系不会发生变化

GC收集器

  • 新生代

    Serial

    • 单线程,进行GC时,必须暂停其他工作线程,直到GC结束
    • Client模式下默认的新生代收集器

    ParNew

    • Serial的多线程版
    • Server模式下默认的新生代收集器(与CMS收集器配合)

    Parallel Scavenge

    • 目标是达到一个可控制的吞吐量
    • 可开启GC自适应的调节策略
    • 复制算法 & 多线程
  • 老年代

    Serial Old

    • Serail的老年代版本
    • 标记 - 整理

    Paraller Old

    • Parallel Scavenge的老年代版本
    • 多线程 & 标记 - 整理

    CMS

    • 获取最短回收停顿时间为目的
    • 标记清除
      • 初始标记
        标记GC Roots能直接关联的对象
      • 并发标记
        GC Roots Tracing
        可以和用户线程一起工作
      • 重新标记
        修正并发标记期间因程序运行而导致标记产生变动的部分
      • 并发清除
        可以和用户线程一起工作
    • 缺点
      • 对CPU资源敏感 : 会导致程序变慢 ,总吞吐量降低
      • 无法清理浮动垃圾 : 边运行边清理,出现在标记后的垃圾,只好等待下一次GC
      • 产生大量空间碎片: 标记 - 清除
  • G1

    • 并行 & 并发
    • 分代收集(不需要其他收集器配合)
    • 空间整合 : 将Java堆划分为多个Region,从整体来看基于标记-整理,从局部来看基于复制算法
    • 可预测的停顿: 建立可预测的停顿时间模型,能让使用者指明在一个M毫秒的时间片段内,GC时间不超过N毫秒
    • 收集过程(类似CMS)
      • 初始标记
      • 并发标记
      • 最终标记
      • 筛选回收 : 跟踪Region中垃圾堆积的价值大小,优先回收价值最大的(所以叫Garbage First)

内存分配&回收策略

  • 对象优先在Eden分配 , 当Eden区空间不足时, 会触发一次Minor GC
    • Minor GC : 发生在新生代的GC,频繁且速度快
    • Full GC : 发生在老年代的GC
  • 大对象直接进入老年代
  • 长期存活的对象进入老年代
    • 每个对象有一个年龄计数器
    • 在Eden出生,熬过第一次Minor GC并能被Survivor容纳,将移动到Survivor空间
    • 在Survivor每熬过一次Minor GC,年龄会加一岁,年龄增长到一定程度,会晋升老年代
  • 如果Survivor中,所有相同年龄k的对象大小总和>Survivor空间大下/2 ,则年龄大于k的对象直接进入老年代
  • 空间分配担保
    • Minor GC之前,检查老年代最大可用连续空间是否大于新生代所以对象总空间,如果成立,则此次Minor GC是安全的
    • 如果不成立,检查是否允许担保失败参数
      • 允许 : 冒风险进行Minor GC(取每次晋升老年代对象大小平均值作为经验值)
      • 不允许: 进行一次Full GC
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值