前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jvm系列之垃圾收集算法

jvm系列之垃圾收集算法

作者头像
六个核弹
发布2022-12-23 20:48:58
2280
发布2022-12-23 20:48:58
举报

jvm系列之垃圾收集算法

1 标记-清除算法

标记-清除算法是最基础的算法,算法分为标记和清除两个阶段,首先标记出要清除的对象,在标记完后统一回收所有被标记的对象,标记方式为j《jvm系列之垃圾收集器》里面所提到的。这种算法标记和清除两个过程效率都不高;并且在标记清除后,内存空间变得很零散,产生大量内存碎片。当需要分配一个比较大的对象时有可能会导致找不到足够大的内存。 标记清除算法图解(图片来源于百度图片):

2 复制算法

   为了解决标记清除效率低的问题,出现了复制算法;这种算法将内存划分为大小相等的两块内存,只使用其中一块。当这一块内存使用完了就将存活的对象复制到另一块上面去,然后把已使用的内存空间一次性清理掉,这种方法不必考虑内存碎片的情况,运行高效,实现简单。缺点是浪费了一半的内存。复制算法图解(图片来源百度图片):

3 标记-整理算法

   复制收集算法在对象存活率较高的时候就要进行较多的复制操作,导致效率变低。而且老年代很少会有内存回收,对老年代而言,复制算法做了大量的无用功。针对复制算法存在的的问题,有人提出了标记-整理算法。标记过程和标记-清除算法过程一样,但后续不是直接对可回收对象进行清理,而是让所有存活对象都向一方移动,整理内存,然后再进行清理。标记-整理算法图解(图片来源百度图片):

4 分代收集算法

   分代收集算法思路是根据对象存活周期不同将内存划分为几块。一般是分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中每次收集时都会回收很多内存,选用高效率的复制算法,并且只需要预留少量的复制空间,用于复制存活对象。老年代中因为对象存活率高,采用标记-整理或标记清理算法节省内存空间提高清理效率。

5 各版本jdk垃圾收集器一览

收集器名称

区   域

说明

Serial

新生代

单线程,GC时必须停止其它线程直到收集结束;JVM运行在client模式下新生代的默认收集器,简单有效;采用复制算法

ParNew

新生代

Serial收集的多线程版,保留Serial的参数控制,算法等,暂停所有用户线程,采用复制算法;JVM运行在server的首先的新生代收集器;只有它能和CMS配合工作

Parallel Scavenge

新生代

采用复制算法,并行的多线程收集器,与ParNew不同的是,关注点不是停顿时间,而是可控制的吞吐量,即运行用户代码的时间/(运行用户代码的时间+垃圾收集的时间)。可设置最大GC时间和吞吐量大小等参数,也可以让JVM自适应调整策略

CMS

新生代

concurrent Mark Sweep,已获取最短回收停顿为目标,大部分的互联网站及服务端采用的方式,标记-清除算法

G1

新生代/老年代

收集器最前沿版本,JDK 1.7,代替CMS的新产品

Serial Old(MSC)

老年代

Serial的老年版,单线程收集器,采用标记-整理算法,主要是client模式的JVM使用

Parallel Old

老年代

Parallel Scavenge的老年版,多线程,标记整理算法

jdk11 垃圾收集器——ZGC

   (网上搜的)ZGC是一个处于实验阶段的,可扩展的低延迟垃圾回收器,旨在实现以下几个目标:

  • 停顿时间不超过10ms
  • 停顿时间不随heap大小或存活对象大小增大而增大
  • 可以处理从几百兆到几T的内存大小

限制:

  • 当前版本不支持类卸载
  • 当前版本不支持JVMCI

ZGC包含10个阶段,但是主要是两个阶段标记和relocating。GC循环从标记阶段开始,递归标记所有可达对象,标记阶段结束时,ZGC可以知道哪些对象仍然存在哪些是垃圾。ZGC将结果存储在每一页的位图(称为live map)中。在标记阶段,应用线程中的load barrier将未标记的引用压入线程本地的标记缓冲区。一旦缓冲区满,GC线程会拿到缓冲区的所有权,并且递归遍历此缓冲区所有可达对象。注意:应用线程负责压入缓冲区,GC线程负责递归遍历。

   标记阶段后,ZGC需要迁移relocate集中的所有对象。relocate集是一组页面集合,包含了根据某些标准(例如那些包含最多垃圾对象的页面)确定的需要迁移的页面。对象由GC线程或者应用线程迁移(通过load barrier)。ZGC为每个relocate集中的页面分配了转发表。转发表是一个哈希映射,它存储一个对象已被迁移到的地址(如果该对象已经被迁移)。GC线程遍历relocate集的活动对象,并迁移尚未迁移的所有对象。有时候会发生应用线程和GC线程同时试图迁移同一个对象,在这种情况下,ZGC使用CAS操作来确定胜利者。一旦GC线程完成了relocate集的处理,迁移阶段就完成了。虽然这时所有对象都已迁移,但是旧地引用址仍然有可能被使用,仍然需要通过转发表重新映射(remapping)。然后通过load barrier或者等到下一个标记循环修复这些引用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 六个核弹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • jvm系列之垃圾收集算法
    • 1 标记-清除算法
      • 2 复制算法
        • 3 标记-整理算法
          • 4 分代收集算法
            • 5 各版本jdk垃圾收集器一览
              • jdk11 垃圾收集器——ZGC
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档