专栏首页Jed的技术阶梯图解 JVM GC 过程

图解 JVM GC 过程

1. Minor GC

(1) Minor GC过程

假设现在Heap内存大小为20M,其中年轻代为10M,老年代为10M,年轻代中Eden区6M,From区2M,To区2M,新创建的对象首先往Eden区分配,当再次分配一个对象,假设大小为1M,此时Eden区已经没有足够空间来给这个对象分配内存,如图所示:

这时候触发一次Minor GC,把Eden区的存活对象转移到From区,非存活对象进行清理,然后给新创建的对象分配空间,存入Eden区

随着分配对象的增多,Eden区的空间又不足了:

这时候再触发一次Minor GC,清理掉Eden区和S1区的死亡对象,把存活对象转移到S2区,然后再给新对象分配内存:

From区和To区是相对的关系,哪个区中有对象,哪个区就是From区,比如,再进行一次Minor GC,会把存活对象转移到S1区,再为转移之前,S2区是From区,S1区是To区,转移后,S2区中没有存活对象,变为To区,而S1区变为From区:

2. 对象进入老年代的4种情况

(1) 假如进行Minor GC时发现,存活的对象在ToSpace区中存不下,那么把存活的对象存入老年代

(2) 大对象直接进入老年代

假设新创建的对象很大,比如为5M(这个值可以通过PretenureSizeThreshold这个参数进行设置,默认3M),那么即使Eden区有足够的空间来存放,也不会存放在Eden区,而是直接存入老年代

(3) 长期存活的对象将进入老年代

此外,如果对象在Eden出生并且经过1次Minor GC后仍然存活,并且能被To区容纳,那么将被移动到To区,并且把对象的年龄设置为1,对象没"熬过"一次Minor GC(没有被回收,也没有因为To区没有空间而被移动到老年代中),年龄就增加一岁,当它的年龄增加到一定程度(默认15岁,配置参数-XX:MaxTenuringThreshold),就会被晋升到老年代中

(4) 动态对象年龄判定

还有一种情况,如果在From空间中,相同年龄所有对象的大小总和大于From和To空间总和的一半,那么年龄大于等于该年龄的对象就会被移动到老年代,而不用等到15岁(默认):

4. Full GC

如果某个(些)对象(原来在内存中存活的对象或者新创建的对象)由于以上原因需要被移动到老年代中,而老年代中没有足够空间容纳这个(些)对象,那么会触发一次Full GC,Full GC会对整个Heap进行一次GC,如果Full GC后还有无法给新创建的对象分配内存,或者无法移动那些需要进入老年代中的对象,那么JVM抛出OutOfMemoryError

5. 空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlerPromotionFailure这个参数设置的值(true或flase)是否允许担保失败(如果这个值为true,代表着JVM说,我允许在这种条件下尝试执行Minor GC,出了事我负责)。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者HandlerPromotionFailure为false,那么这次Minor GC将升级为Full GC

如果老年代最大可用的连续空间大于历次晋升到老年代对象的平均大小,那么在HandlerPromotionFailure为true的情况下,可以尝试进行一次Minor GC,但这是有风险的,如果本次将要晋升到老年代的对象很多,那么Minor GC还是无法执行,此时还得改为Full GC。

HandlerPromotionFailure为true时,如果某次需要转移到老年代中的对象确实很多,老年代无法容纳,那么也会先尝试进行一次Minor GC,Minor GC无法执行时再进行Full GC,这样虽然绕了圈子,但我们还是建议把这个参数设置为true,因为我们要尽量避免Full GC。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • spark读写HBase之使用hortonworks的开源框架shc(二):入门案例

    shc测试环境的搭建参考: spark读写HBase之使用hortonworks的开源框架shc(一):源码编译以及测试工程创建

    CoderJed
  • 在VMware Workstation中安装完CentOS-7.6-Minimal版后的常用配置

    首先确定可以设置的IP地址,在vmware的虚拟网络配置中查看自己的虚拟网络网段:

    CoderJed
  • Azkaban-3.x solo-server 模式部署

    solo-server模式:使用内置的数据库H2,并且Web服务器和Executor服务器都在同一进程中运行

    CoderJed
  • JVM GC 那些事(二)- 堆上的内存分配机制

    前一篇文章JVM GC 那些事(一)- JVM 运行时内存划分介绍了 JVM 运行时的内存划分情况。本文将介绍 JVM GC “主战场” 堆上的内存分配机制。

    codingforfun
  • 横扫13项中文NLP任务:香侬科技提出汉语字形表征向量Glyce+田字格CNN

    汉字是一种象形文字,可以被分解为更小、更基础的音义结合体:象形(即对象的图像化表述,如「亻」、「日」、「木」)和形声(用于发音,如「晴」中的「青」)。汉朝的《说...

    机器之心
  • 每日科技报-互联网论功行赏

    一、都是央视“群发短信我不回”害的 尽管三大运营商还未公布今年拜年短信的数量,但一些运营商地方分公司的统计显示,今年拜年短信同比去年肯定下降了,降幅在10%至2...

    罗超频道
  • JVM中的Safepoints

    java程序员都听说过GC,大家也都知道GC的目的是扫描堆空间,然后将那些标记为删除的对象从堆空间释放,以提升可用的堆空间。

    程序那些事
  • 响应式编程中 Stream 对象的实现原理

    这篇文章介绍一种编程泛型,叫做响应式编程。将响应式称作“编程泛型”可能有些夸大其作用范畴,不过通过引入响应式确实会改变我们对特定问题的思考方法,就像刚接触red...

    腾讯IVWEB团队
  • JavaScript概览

    近日的项目需要用JavaScript完成,于是决定通读《JavaScript高级程序设计第三版》,书是2012年的,比较老了,但是可以用来快速了解JavaScr...

    刘开心_1266679
  • mongoDB在互联网金融的应用

    摘要 本次分享主要讲mongodb 在互联网金融中交易与非交易部分如何实践,金融行业涉及哪些注意点,又踩过的坑。 ? 什么是P2P ? P2P是一种网上的借贷模...

    IT大咖说

扫码关注云+社区

领取腾讯云代金券