栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JVM】06 堆 -> 02 对象分配过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JVM】06 堆 -> 02 对象分配过程

对象分配过程
    • 1.对象分配难点
    • 2.图解对象分配过程
    • 3.额外补充
    • 4.对象分配的特殊情况
    • 5.代码演示对象分配过程

1.对象分配难点
  • 为新对象分配内存是一件非常严谨和复杂的任务,JVM的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法与内存回收算法密切相关,所以还需要考虑GC执行完内存回收后是否会在内存空间中产生内存碎片。
2.图解对象分配过程
  1. 起初创建对象,对象都分配在Eden区,此区有大小限制。

  2. 当Eden区满了,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Young/Minor GC),GC会导致用户线程阻塞,在此期间JVM将伊甸园区中的不再被其他对象所引用的对象进行销毁,并且将Eden区中存活的对象移动到其中一个Survivor区,GC结束后,再加载新的对象时,将其放到Eden区

    补充说明:
    图中绿色的是存活的,GC后仍然存活的,会被放进其中一个Survivor from区
    每个对象都会有年龄计数器,每发生一次GC,存活下来的话都会加一。

  3. Eden区继续存放对象,当Eden区再次存满的时候,又会触发一个MinorGC操作;此时GC将会把 Eden和Survivor From中的对象进行一次垃圾收集,把存活的对象放到 Survivor To区,同时让存活的对象年龄 + 1

    补充说明:
    Survivor from 区和 Survivor to区依次交换。复制之后有交换,谁空谁是to。

  4. 年龄等于15的(经过15次minor GC的)对象,再次发生GC时就会被移动到养老区;没有15的仍然在survivor两个区中轮转

    我们继续不断的进行对象生成和垃圾回收,当Survivor中的对象的年龄达到15的时候,将会触发一次 Promotion 晋升的操作,也就是将年轻代中的对象晋升到老年代中


3.额外补充

(1) 进入老年代的阈值
默认超过15次,就会移动到养老区。
可以使用 -XX:MaxTenuringThreshold= 参数进行设置。

(2) Minor GC触发机制
注意:只有Eden满了才会触minorGC/youngGC,而幸存者区满了是绝对不会触发minorGC的。

(3) Major GC 和 OOM
在养老区,相对悠闲。当老年区内存不足时,再次触发GC:Major GC,进行养老区的内存清理。若养老区执行了Major GC之后发现依然无法进行对象的保存,就会产生OOM异常。

(4) 关于垃圾回收
频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间收集。

(5) 进入老年代有两种方式

  • 一种是年纪到达阈值。
  • 另一种是在年轻代满了,仍然添加对象的时候,会有老年代担保,直接进入老年代。
4.对象分配的特殊情况

  • 特殊情况1:超大对象
  • 当来了一个新对象申请堆内存,Eden区存放不下,发生MinorGC,此时Eden区会被清空;Minor GC后,如果Eden区仍然放不下这个对象,说明这个对象是一个超大对象,此时只能直接放进老年代;
  • 当老年代都放不下了,则先触发Full GC ,再看看能不能放下但如果还是放不下,那只能报 OOM 啦~~~
  • 特殊情况2:S区无法存放下存活对象
  • 如果 Eden 区满了,在Minor GC的过程中,会判断S区能不能放的下存活的对象,放得下就将对象往幸存区拷贝,发现幸存区放不下啦,那只能便宜了某些新对象,让他们直接晋升至老年区
5.代码演示对象分配过程


当老年代放不下了就oom了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/603137.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号