【转帖】一道面试题:JVM老年代空间担保机制

一道,面试题,jvm,年代,空间,担保,机制 · 浏览次数 : 0

小编点评

**老年代空间担保机制** 老年代空间担保机制是一种对新生代对象的动态空间分配机制,用于优化JVM内存利用率。当老年代可用空间小于新生代所有对象的总大小时,就会触发空间担保机制。 **担保过程** 1. 每次Minor GC之前,老年代可用空间会和新生代所有对象的总大小进行比较。 2. 如果老年代可用空间大于新生代所有对象的总大小,则可以直接进行MinorGC,因为即使MinorGC后所有对象都活着,S区放不下,也可以放到老年代中。 3. 如果老年代的可用空间小于新生代所有对象的总大小,就会进行下一个判断,判断老年代的可用空间和新生代每次MinorGC后进入老年代对象的平均大小。 4. 如果发现老年代的可用内存大于每次MinorGC后进入老年代对象的平均大小,则可以尝试进行MinorGC,但是有可能出现MinorGC后所有对象都存活,全部进去老年代,导致老年代可用空间不足,触发FullGC。 5. 反之,如果老年代的可用空间小于每次MinorGC后进入老年代对象的平均大小,则会触发FullGC。 **老年代空间担保机制的目的是** * 避免频繁进行FullGC,以保持JVM的性能。 * 优化内存利用率,减少内存碎片。 **老年代空间担保机制的缺点** * 如果空间分配担保失败,会触发Full GC。 * 为了获得性能提升,需要设置老年代空间担保参数,这可能会影响内存分配效率。

正文

面试问题

昨天面试的时候,面试官问的问题:

  1. 什么是老年代空间担保机制?担保的过程是什么?
  2. 老年代空间担保机制是谁给谁担保?
  3. 为什么要有老年代空间担保机制?或者说空间担保机制的目的是什么?
  4. 如果没有老年代空间担保机制会有什么不好?
    下面我们就带着这些问题去了解一下JVM老年代空间担保机制吧。

老年代空间担保机制

在这里插入图片描述
如图,在每次MinorGC之前,老年代可用空间会和新生代所有对象的总大小进行对比,如果老年代可用空间大于新生代所有对象的总大小,就可以直接进行MinorGC,因为即使MinorGC后所有对象都活着,S区放不下,也可以放到老年代中。如果老年代的可用空间小于新生代所有对象的总大小,就会进行下一个判断,判断老年代的可用空间和新生代每次MinorGC后进入老年代对象的平均大小,如果发现老年代的可用内存大于每次MinorGC后进入老年代对象的平均大小(举个例子:之前每次Minor GC后,平均都有10MB左右的对象会进入老年代,那么此时老年代可用内存大于10MB。这就说明很可能这次Minor GC过后也是差不多10MB左右的对象会进入老年代,此时老年代空间是够的),那么可以尝试进行MinorGC,但是有可能出现MinorGC后所有对象都存活,全部进去老年代,导致老年代可用空间不足,(例:老年代剩余100M,新生代中对象总大小为200M,但是每次MinorGC后平均进入老年代的对象大小为80M,但是此次MinorGC后所有对象全部存活,导致老年代可用空间不足)此时就会触发FullGC。反之,如果老年代的可用空间小于每次MinorGC后进入老年代对象的平均大小,则会触发FullGC。如果FullGC之后,老年代也没有足够的可用空间存放新生代的对象,则会出现OOM内存溢出。

了解了这个担保流程之后,我们再来看我们的面试题:

  1. 什么是老年代空间担保机制?担保的过程是什么?
    上面文字解释的就是。
  2. 老年代空间担保机制是谁给谁担保?
    我理解的是老年代给新生代的S区做担保。
  3. 为什么要有老年代空间担保机制?或者说空间担保机制的目的是什么?
    目的:避免频繁的进行FullGC。
  4. 如果没有老年代空间担保机制会有什么不好?
    如果没有这个担保机制,就会直接执行Full GC,这样对性能的影响频次会增加。

哪些对象会进行老年代

  • 动态对象年龄判断:当前放对象的Survivor区域里,一批对象的总大小大于了这块Survivor区域的内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代了。
  • 大对象直接进入老年代。
  • 15次Minor GC后还存活的对象。
  • Minor GC后的对象太多无法放入Survivor区。

Full GC的触发时机

  • 老年代空间不足。比如大对象或者年龄超过15的对象进入老年代。
  • 空间分配担保失败。这个就是咱们今天说的这种情况。老年代可用内存小于新生代全部对象的大小,如果没开启空间担保参数,会直接触发Full GC,所以一般空间担保参数都会打开。
  • Concurrent Mode Failure 执行CMS GC的过程中同时有对象要进入老年代,而此时老年代空间不足(可能是GC过程中浮动垃圾过多导致暂时性的空间不足)便会报Concurrent Mode Failure错误并触发Full GC。这种情况下会使用Serial Old收集器,也就是发生了退化,CMS退化为serial gc,Serial Old收集器是单线程的,对GC的影响很大。concurrent mode failure产生的原因是老年代剩余的空间不够,导致了和gc线程并发执行的用户线程创建的大对象(由PretenureSizeThreshold控制新生代直接晋升老年代的对象size阀值)不能进入到老年代,只要stop the world来暂停用户线程,执行GC清理,单线程对全堆以及 metaspace 进行回收,STW 的时间会特别长,对业务系统的可用性影响比较大。可以通过设置CMSInitiatingOccupancyFraction预留合适的CMS执行时剩余的空间。
  • 老年代可用内存小于历次新生代GC后进入老年代的平均对象大小,此时会提前Full GC;但是"-XX:HandlePromotionFailure"参数,在JDK 1.6以后就被废弃了,所以现在一般都不会在生产环境里设置这个参数了。在JDK 1.6以后,只要判断"老年代可用空间"大于"新生代对象总和"或者"老年代可用空间"大于"历次Minor GC升入老年代对象的平均大小",两个条件满足一个,就可以直接进行Minor GC,不需要提前触发Full GC了。
  • 新生代Minor GC后的存活对象大于Survivor,那么就会进入老年代,此时老年代内存不足,触发Full GC。这里的不足就是判断条件后还是不足或者经过判断后进行YGC后放入老年代此时的空间不足,然后进行Full GC,就会出现频繁Full GC。达到一定情况后,就会OOM了。
  • 如果用的是CMS收集器,老年代可用内存大于历次新生代GC后进入老年代的对象平均大小,但是老年代已经使用的内存空间超过了("-XX:CMSInitiatingOccupancyFaction=92%"JDK6默认值 )这个参数指定的比例,也会自动触发Full GC。
  • 未指定老年代和新生代大小,堆伸缩时会触发Full GC。
  • 调用System.gc(),只是建议虚拟机执行Full GC,但虚拟机不一定真正去执行。
文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览118057 人正在系统学习中

与【转帖】一道面试题:JVM老年代空间担保机制相似的内容:

【转帖】一道面试题:JVM老年代空间担保机制

面试问题 昨天面试的时候,面试官问的问题: 什么是老年代空间担保机制?担保的过程是什么?老年代空间担保机制是谁给谁担保?为什么要有老年代空间担保机制?或者说空间担保机制的目的是什么?如果没有老年代空间担保机制会有什么不好? 下面我们就带着这些问题去了解一下JVM老年代空间担保机制吧。 老年代空间担保

[转帖]JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

《深入理解java虚拟机》+宋红康老师+阳哥大厂面试题2总结整理 一、堆的结构组成 堆位于运行时数据区中是线程共享的。一个进程对应一个jvm实例。一个jvm实例对应一个运行时数据区。一个运行时数据区有一个堆空间。 java堆区在jvm启动的时候就被创建了,其空间大小也就被确定了(堆是jvm管理的最大

[转帖]JVM参数之-XX:SurvivorRatio

https://www.cnblogs.com/hellxz/p/10841550.html 最近面试过程中遇到一些问JVM参数的,本着没用过去学习的办法看了些博客写得不准确,参考oracle的文档记录一下,争取每天记录一点知识点 -XX:SurvivorRatio=6 ,设置的是Eden区与每一个

【转帖】8.JVM双亲委派机制(面试常问)

目录 1.什么是双亲委派机制?2.双亲委派机制的优势3.沙箱安全机制 1.什么是双亲委派机制? 双亲委派机制工作原理:(面试) 1.如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行。 2.如果父类的加载器还存在其父类加载器,则进一步向上委托,依次递归,请

[转帖]十二、G1垃圾收集器

G1收集器是一款面向服务器的垃圾收集器,也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命。为什么对G1收集器给予如此高的期望呢?既然对G1收集器寄予了如此高的期望,那么他一定是有特别之处。他和其他的垃圾收集器有何不同呢?下面我们将从以下几个方面研究G1收集器。 一、为什么会诞生G

[转帖]G1收集器基本介绍(-XX:+UseG1GC)

概述G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC 停顿时间要求的同时,还具备高吞吐量性能特征. 停顿时间要求的同时,还具备高吞吐量性能特征. G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可

[转帖]JVM——内存区域:运行时数据区域详解

https://www.jianshu.com/p/cded765cfd1b 关注:CodingTechWork,一起学习进步。 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象、一个是面向过程编程以外,我们还会从底层内存管理和垃圾收集方面作出比较。 对于C++

[转帖]redis脑裂是什么?如何解决

这也是一个常见面试题,对redis集群部署不熟悉的同学,可能压根没听过这个名词qvq 什么是redis脑裂 下面我们解释一下什么是redis脑裂: 关于reids集群会由于网络等原因出现脑裂的情况,所谓的集群脑裂就是,由于redis master节点和redis salve节点和sentinel处于

[转帖]Java连接 MySQL详细教程,分享复习经验和后台开发面经

(由于安装了汉化包,英文版的用户可以对应图标来操作) 选中菜单栏文件,之后选择项目结构 选择Libraries 点击+ ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210321181721553.png?x-oss- 【一线大厂Java面试题解析+后端开发学

[转帖]2022年 SRE、DevOps技能图谱

https://zhuanlan.zhihu.com/p/568752990 在过去一段时间,我面试过一些 DevOps 相关从业者,并且曾经收到过一些知乎小伙伴的提问,针对于 DevOps 以及相关从业者而言,我个人认为这块的要求是比较高的,因为它对 相关技能 以及 工作经验都有一定要求,并且在落