1.躲过15次GC之后进入老年代

系统刚启动时,创建的各种各样的对象,都是分配在年轻代里。

随着慢慢系统跑着跑着,年轻代满了,就会出发Minor GC ,可能1%的少量存活对像转移到空着的Survivor区中

然后系统继续运行,继续在Eden区里分配对象........

.....

类似静态变量等引用的对象,可能存活时间会久一些,无论年轻代中怎么垃圾回收,类似这种对象都不会被回收掉。

而此对象每次在年轻代里躲过一次Minor GC被转移到一块Survivor区域中,他的年龄就会增加一岁

默认的设置下,当对象的年龄达到15岁时,也就是躲过15次GC的时候,他就会转移到老年代里去。

具体是多少岁进入老年代,可以通过JVM参数“-XX:MaxTenuringThreshold”来设置,默认是15岁

2.动态对象年龄判断

这里跟这个对象年龄有另外一个规则可以让对象进入老年代,不用等到15次GC过后才可以。

他的大致规则就是,假如说当前放对象的Survivor区域里,一批对象的总大小大于了这块Survivor区域的内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代了。

假设这个图中的Survivor2区有两个对象,这俩对象的年龄一样,都是2岁

然后俩对象加起来内存超过了50MB,这个时候,Survivor2区里大于等于2岁的对象,都要进入老年代里去。

这就是动态年龄判断的规则,这条规则也会让一些年轻代的对象进入老年代

另外实际这个规则运行的时候是如下的逻辑:年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区的50%,此时就会把年龄n以上的对象都放入老年代。

3.大对象直接进入老年代

有一个JVM参数,就是“-XX:PretenureSizeThreshold”,可以把它的值设置为字节数,比如“1048576”字节,就是1MB

意思就是如果你要创建一个大于这个大小的对象,比如一个超大的数组,或者是别的啥东西,此时就直接把这个大对象放到老年代里去,压根不会经过年轻代。

之所以这么做,是因为要避免年轻代里出现那种大对象,然后屡次躲过GC,还得把他在两个Survivor区域里来回复制多次之后才能进入老年代。

所以说这也是一个对象进入老年代的规则

4.Minor GC后的对象太多,无法放入Survivor区

如图所示:

这个时候就必须得把这些对象直接转移到老年代去!

5.老年代空间分配担保规则

如果年轻代里大量对象存活,确实自己的Survivor区放不下了,必须转移到老年代去

但是如果老年代里空间也不够放这些对象,改怎么办呢?

首先,在执行任何一次Minor GC之前,JVM都会先检查一些老年代可用的内存空间,是否大于年轻代所有对象的总大小

问什么呢?因为最极端的情况下,可能年轻代Minor GC之后,所有对象都存活下来了,那岂不是年轻代所有对象全部进入老年代

如果说发现老年代内存大小是大于年轻代所有对象的,此时就可以放心大胆地对年轻代发起一次Minor GC了。

但是假如执行Minor GC之前,发现老年代的可用内存已经小于了年轻代的全部对象大小了

恰好这个时候Minor GC之后年轻代的对象全部存活下来,全部需要转移到老年代中去,但是老年代内存空间又不够?

所以假如Minor GC之前,发现老年代的可用内存已经小于了年轻代的全部对象大小,就会看一个“-XX:-HandlePromotionFailure”的参数是否设置了

如果有这个参数,那么就会看看老年代的内存大小,是否大于之前每一次Minor GC后进去老年代对象的平均大小

但是如果上面步骤判断失败了,或者是“-XX:-HandlePromotionFailure”参数没设置,此时就会直接触发一次“Full GC”,

就是对老年代进行垃圾回收,尽量腾出来一些内存空间,然后再执行Minor GC。

如果上面两个步骤判断成功,那么就可以尝试Minor GC,此时进行Minor GC有几种可能:

①Minor GC过后,剩余的存活对象的大小,小于Survivor区的大小,那么此时存活对象进入Survivor区即可

②Minor GC过后,剩余的存活对象的大小,大于Survivor区的大小,但是小于老年代可用内存大小,就直接进入老年代即可

③Minor GC过后,剩余的存活对象的大小,大于Survivor区的大小,同时大于老年代可用内存大小,此时就会发生“Handle Promotion Failure”的情况,这个时候就会出发一次“Full GC”。

Full GC就是对老年代进行垃圾回收,同时也一般会对年轻代进行垃圾回收。

如果Full GC之后,老年代还是没有足够空间存放Minor GC过后的剩余存活对虾,此时就会导致所谓的“OOM”内存溢出了。

6.老年代垃圾回收算法

老年代触发垃圾回收的机制,一般就是两个;

①在Minor GC之前,一通检查发现很可能Minor GC之后要进入老年代的对象太多了,老年代放不下,此时需要提前触发Full GC再然后再带着进行Minor GC;

②要不然是在Minor GC之后,发现剩余对象太多放入老年代都放不下了。

老年代采取的垃圾回收算法是标记整理算法

看下面图,首先标记出来老年代当前存活的对象,这些对象可能是东一个西一个的

接着会让这些存活对象在内存里进行移动,把存活对象尽量都挪动到一边去,让存活对象紧凑的靠在一起,避免垃圾回收过后出现过多的内存碎片

然后再一次性把垃圾对象都回收掉,如下图

老年代的垃圾回收算法的速度至少比年轻代的垃圾回收算法的速度慢10倍。

如果系统频繁出现老年代的Full GC垃圾回收,会导致系统性能被严重影响,出现频繁卡顿的情况。

所以,所谓的JVM优化,就是尽可能的让对象都在年轻代里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免年轻代频繁的进行垃圾回收。

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览56861 人正在系统学习中

[转帖]JVM中年轻代里的对象什么情况下进入老年代?以及老年代垃圾回收算法-标记整理算法的更多相关文章

  1. JVM内存管理------GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  2. JVM内存管理之GC算法精解(复制算法与标记/整理算法)

    本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...

  3. 聊聊JVM的年轻代

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的 唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候 ...

  4. 聊聊JVM的年轻代(转)

    聊聊JVM的年轻代 本文转自http://ifeve.com/jvm-yong-generation/ 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代 ...

  5. JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法

    标记-清除算法 此垃圾收集算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记对象,它的标记过程前面已经说过——如何判断对象是否存活/死去 死去的对象就会 ...

  6. JVM虚拟机(四):JVM 垃圾回收机制概念及其算法

    垃圾回收概念和其算法 谈到垃圾回收(Garbage Collection)GC,需要先澄清什么是垃圾,类比日常生活中的垃圾,我们会把他们丢入垃圾箱,然后倒掉.GC中的垃圾,特指存于内存中.不会再被使用 ...

  7. jvm垃圾回收机制和常见算法

    这是朋友给的面试题里边的,具体地址已经找不到,只能对原作者说声抱歉了: 理论上来讲sun公司只定义了垃圾回收机制规则,而步局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同. GC(Gar ...

  8. JVM垃圾回收机制和常用算法

    由于疫情的原因,所以目前一直在家远程办公,所以很多时间在刷面试题,发现2019大厂的面试虽然种类很多,但是总结了一下发现主要是这几点:算法和数据结构. JVM.集合.多线程.数据库这几点在面试的时候比 ...

  9. 在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法

    在jsp中选中checkbox后 将该记录的多个数据获取,然后传到Action类中进行后台处理 双主键情况下 *.hbm.xml中的写法   ==========方法1: --------1. 选相应 ...

  10. JVM 垃圾回收机制和常见算法

    垃圾回收机制:释放那些不再持有引用的对象的内存. 如何判断对象是否需要回收? 引用计数:对象,内存,磁盘空间等被引用次数保存起来,次数为0时将其进行释放. 对象引用遍历:对象应用遍历从一组对象开始,沿 ...

随机推荐

  1. 【源码系列#05】Vue3响应式原理(Ref)

    Ref & ShallowRef ref:接受一个参数值并返回一个响应式且可改变的 ref 对象.ref 对象拥有一个指向内部值的单一属性 .value 可以将 ref 看成 reactive ...

  2. 通过印模生成电子印章-Java源代码

    以下代码是处理印模图片的核心代码,通过以下代码可以将公章图片转换为电子印章图片. 制作方式分为四步: 1.在白纸上加盖印章: 2.把加盖印章的白纸扫描,形成图片: 3.将图片通过下面的代码进行自动透明 ...

  3. Harbor私有镜像仓库搭建

    为什么选择Harbor 你可能会问既然我们已经有了 Docker 镜像仓库为什么还需要 Harbor 呢?嗯,Harbor 是 Docker 镜像仓库的企业级扩展,用途更广泛.这些新的企业级功能包括: ...

  4. maven 实现pb的实时编译

    <properties> <protobuf.version>3.15.7</protobuf.version></properties> <ex ...

  5. 实战案例丨GaussDB for DWS如何识别坏味道的SQL

    摘要:SQL中的坏味道,你知道吗? SQL语言是关系型数据库(RDB)的标准语言,其作用是将使用者的意图翻译成数据库能够理解的语言来执行.人类之间进行交流时,同样的意思用不同的措辞会产生不同的效果. ...

  6. 连Python都不熟也能跑通AI人脸识别?“隐藏Boss”竟是它!

    摘要:先把AI人脸识别跑起来,然后研究它是如何实现的,整个过程中确实收获不少.所谓先跟着做,再跟着学,实践与理论结合,自己感觉有理解了一些基础概念入个门,在此分享一下自己的捣鼓经验. 1.买台小&qu ...

  7. 利用Appuploader上架IPA步骤

      Appuploader可以辅助在Windows.linux或mac系统直接申请iOS证书p12,及上传ipa到App Store.方便在没有苹果电脑情况下上架IPA操作. 一.下载安装iOS上架辅 ...

  8. 详解 SSL(二):SSL 证书对网站的好处

    在如今谷歌.百度等互联网巨头强制性要求网站 HTTPS 化的情况下, 网站部署 SSL 证书已然成为互联网的发展趋势.而在上一篇< 详解 SSL(一):网址栏的小绿锁有什么意义?>中,我们 ...

  9. 自媒体时代的贤内助——AI 视频云

    视频,通常是一段由活动画面组成的传递信息的内容.在如今这个信息爆炸的时代,我们每天都要在浩瀚的内容海洋中寻找需求的信息.一个视频是否吸引人内容固然是最重要的,但是播放是否流畅,画质是否清晰的影响力也不 ...

  10. GitLab--简单使用

    1 创建项目组 项目组说明 Private 私有 只有所有者 组内成员或已分配的用户有查看权限(同GitHub收费版的私有仓库) Internal 内部 拥有GitLab账号的成员可以查看 无账号用户 ...