精华内容
下载资源
问答
  • 文章目录Pre躲过15次GC之后进入老年代动态对象年龄判断大对象直接进入老年代Minor GC后的对象太多,无法放入Survivor区怎么办?老年代空间分配担保规则老年代垃圾回收算法 Pre 上篇文章已经讲清楚了新生代的垃圾...

    在这里插入图片描述


    Pre

    上篇文章已经讲清楚了新生代的垃圾回收算法,包括跟这个垃圾回收算法搭配的新生代内存区域的划分,大家也都清楚了为什么有一块Eden区域和两块Survivor区域

    那么本文就要给大家说说,新生代里的对象一般在什么场景下会进入老年代。

    首先我们来看下面的图,我们写好的代码在运行的过程中,就会不断的创建各种各样的对象,这些对象都会优先放到新生代的Eden区和Survivor1区。

    展开全文
  • 老年代担保什么? 当新生代被分配了大对象(该对象大小可以通过参数设置),或者经过Minor GC后,存活下来的对象,Survivor区放不下,那么这些对象都会被分配到老年代老年代想担保就能担保? 老年代空间也是有限的...

    老年代担保什么?

    当新生代被分配了大对象(该对象大小可以通过参数设置),或者经过Minor GC后,存活下来的对象,Survivor区放不下,那么这些对象都会被分配到老年代。

    老年代想担保就能担保?

    老年代空间也是有限的,既然不是无限大,那么老年代在担保前也得自己掂量下,自己是不是吃的下那些要分配给自己的对象。

    老年代想要担保需要遵守什么规则?

    1. 在执行任何一次Minor GC前,JVM都会检查一下老年代的的可用内存空间,然后和新生代中的所有对象的大小总和做个比较,如果大于新生代中的所有对象的大小总和,那么就可以保证Minor GC后,即使新生代中所有的对象都存活下来,Survivor区放不下,老年代也是能够完全分配下这些对象的。如果老年代的的可用内存空间是小于新生代中的所有对象的大小总和的,那么就要继续走第二步的判断。
    2. 第二步判断,要看看是否设置了“-XX:-HandlePromotionFailure”参数,该参数的作用在于会多加一步判断规则:判断老年代的的可用内存空间是否大于之前每一次Minor GC后进入老年代的对象的平均大小。如果不加这个参数或者这个参数判断失败,同时老年代的的可用内存空间小于新生代中的所有对象的大小总和,就会直接进行Full GC,尽量先腾出一些老年代空间来,然后再触发Minor GC,尽最大努力防止出现OOM。如果“-XX:-HandlePromotionFailure”参数判断是成功的,那么就走第三步。
    3. 第三步就可以试着进行Minor GC了,毕竟该做的判断做了和该满足的条件都有了,此时Minor GC后,如果存活的对象大小小于Survivor区的大小,那么存活的对象直接进入Survivor区。如果存活的对象大小大于Survivor区的大小,却小于老年代大小,那么存活的对象直接进入老年代。最极端的情况就是存活的对象大小大于Survivor区的大小,同时也大于老年代大小,那么此时机会触发一次Full GC,对老年代和新生代统一做一次垃圾回收,腾出空间,方便让Minor GC后存活的对象可以进入老年代。最差的情况就是即使经过了Full GC,老年代空间也还是不够,那么就会爆出OOM了。

    总结

    可以发现Minor GC时,JVM会判断老年代此时是否具有担保的资格,同时设置相应的规则,尽可能的避免出现OOM的情况。

    展开全文
  • java老年代过多

    2020-11-20 15:23:41
    应该是从java G1开始就没有具体的老年代了。 但是在工作中由于使用的是老的GC形式。还是出现了这个问题。下面记录一下自己发现问题,解决问题的方法。 首先下载生产环境dump 使用jvisual 打开dump。老年代持续...

    应该是从java G1开始就没有具体的老年代了。

    但是在工作中由于使用的是老的GC形式。还是出现了这个问题。下面记录一下自己发现问题,解决问题的方法。

     

    1. 首先下载生产环境dump
    2. 使用jvisual 打开dump。老年代持续过高,可能有两个原因
      1. 大对象过多。如果对象太大,会直接分配到老年代
      2. 代码中有leak,造成资源无法回收。
    3. 拿到dump后,看到了有很多 byte 数组过大。看了一下内容,是上传附件的内容导致的。下面是第一版上传附件的后端代码。

    由于需要调用其他服务,所以要把request格式进行转化,不能直接透传。所以用到了ByteArrayResource。应该是转化成了这个地方转化的byte数组。没有及时的进行回收。

     

    开始解决

    方案一:

    1. 最开始打算查看http协议,直接用outputstream,直接写需要的数据。主要为了,不用读取字节数组。然后通过stream copy 减少内存使用。后来写了一点就放弃了。有点麻烦。
    2. 然后看了一下源代码,发现使用的是ByteArrayResource。我想直接使用其他的Resource代替就好了,应该有已经实现的这种累。然后找到了InputStreamResource。替换了以后,发现报错.do not use InputStreamResource if a stream needs to be read multiple times
    3. 我查看了一下代码,我应该没有使用InputStreamResource读取过内容。后来找了一篇帖子发现,AbstractResource读取长度的时候会调用inputSteam,代码如下。

      知道问题,然后避免读取inputStream就好了。重写 contentLeagth 方法。试了一下果然好用。

     

    然后打开-XX:+PrintGC 。发现内存果然会减少。

    实际效果,还得等到上线以后才可以查看效果。

     

     

    展开全文
  • jvm 老年代oom gc.log

    2019-11-11 11:10:59
    一次jvm 老年代oom 的dump文件样例
  • JVM晋升老年代总结

    2020-06-03 21:05:47
    当Survivor区的的内存大小不足以装下下一次Minor GC所有存活对象时,就会启动担保机制,把Survivor区放不下的对象放到老年代; 2. 大对象直接放入老年代 大对象(大小大于-XX:PretenureSizeThreshold的对象)直接...

    1. 担保机制

    当Survivor区的的内存大小不足以装下下一次Minor GC所有存活对象时,就会启动担保机制,把Survivor区放不下的对象放到老年代;

    2. 大对象直接放入老年代

    大对象(大小大于-XX:PretenureSizeThreshold的对象)直接在老年代分配内存;(只对Serial和ParNew收集器有效,对于Parallel Scavenge收集器无效)

    3.长期存活的对象进入老年代

    把age大于-XX:MaxTenuringThreshold的对象晋升到老年代;(对象每在Survivor区熬过一次,其age就增加一岁);

    4.动态年龄判断

    看一段JVM源码

    
    uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
    	//survivor_capacity是survivor空间的大小,计算期望的在回收之后的survivor区的内存量
      size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
      size_t total = 0;
      uint age = 1;
      while (age < table_size) {
        total += sizes[age];//sizes数组是每个年龄段对象大小
        if (total > desired_survivor_size) break;
        age++;
      }
      uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
    	...
    }
    

    TargetSurvivorRatio为我们设置的JVM参数-XX:TargetSurvivorRatio其默认值为50,从代码中可以看到会记录1->n的年龄对象的总内存和,当此值大于我们期望值时,就设置MaxTenuringThreshhold为该age,即>=此age年龄的对象都会晋升到老年代。

    展开全文
  • 对象如何进入老年代 新生代用的是复制算法,老年代用的是标记-清除或标记整理算法。 问题:一般而言,对象首次创建会被放置在新生代的eden区,如果没有gc的介入就不会离开...1:大对象直接进入老年代。比如很长...
  • 文章目录1. Minor GC 和 Full GC 的含义及区别?2. 什么时候对象进入老年代?3. 什么时候会触发Full GC?4. 如何优化GC? 1. Minor GC 和 Full GC 的含义及区别?...Full GC(老年代GC):指发生在老年代的...
  • 对象经过几次垃圾回收,熬到设定的年龄阈值,就会晋升到老年代。 如果直接分配大对象,该大对象超出了JVM设置的限定值,就会直接分配到老年代。 在一次新生代GC后,Survivor区域中的几个年龄对象加起来超过了...
  • jvm的新生代、老年代、永久代关系

    万次阅读 多人点赞 2018-07-08 13:43:44
    原文地址:...通常情况下,对象主要分配在新生代的Eden区上,少数情况下也可能会直接分配在老年代中。Java虚拟机每次使用新生代中的Eden和其中一块Survivor(From)...
  • 新生代和老年代

    千次阅读 2017-05-28 15:28:05
    以下为我学习java新生代和老年代所整理的笔记。摘自《深入理解java虚拟机》一书。 java堆可以细分为新生代和老年代 新生代:生命周期比较短的对象。 老年代:生命周期比较长的对象。 1、新生代常采用的算法:复制...
  • 新生代与老年代

    千次阅读 2016-06-09 18:13:05
    在JAVA中堆被分为两块区域:新生代(young)、老年代(old)。 堆大小=新生代+老年代;(新生代占堆空间的1/3、老年代占堆空间2/3) 新生代又被分为了eden、from survivor、to survivor(8:1:1); 新生代...
  • java 老年代 新生代 永久代

    千次阅读 2018-08-26 23:23:36
    Java GC、新生代、老年代 堆内存  Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 (...
  • 7、老年代进入条件

    2020-03-21 16:18:26
    1、躲过15次GC,进入老年代 可以通过JVM参数 “-XX:MaxTenuringThreshold”来设置,默认情况是15岁 2、分配担保; CMS:将Eden+servivor -->移动到另一个servivor中的时候,...直接进入老年代,跟随老年代...
  • 堆 = 新生代+老年代,但是要注意一点老年代不包括永久代(方法区),也就是说堆内存中只有新生代和老年代,而永久代是指的方法区。 之前介绍过新生代中的垃圾回收机制了,再来介绍一下老年代的垃圾回收机制里面使用...
  • java老年代垃圾回收器

    2019-03-04 12:32:31
    Serial Old收集器(-XX:+...简单高效,Client模式下默认的老年代收集器 Parallel Old收集器(-XX:+UseParallelOldGC , 标记-整理算法 JDK6之后) 多线程,吞吐量优先 CMS收集器(-XX:+UseConcMarkSweepGC , ...
  • JVM堆老年代分配比例

    千次阅读 2018-08-19 08:29:26
    老年代分配 -XX:NewRatio 设置老年代与新生代的比例 -XX:NewRatio=老年代/新生代 尽可能将对象,预留在新生代 减少老年代的GC次数 package com.bjsxt.base001; public class Test02 { public static void...
  • 什么时候进入老年代

    千次阅读 2019-11-02 14:50:51
    Minor GC 和 Full GC 的含义及区别?...Full GC(老年代GC):指发生在老年代的GC,速度一般比 Minor GC 慢十倍以上。如果有Full,说明这次GC发生了Stop-The-World。 什么时候对象进入老年代? 大对象直接进入...
  • 【JVM】Java堆内存的新生代和老年代

    千次阅读 2021-05-09 09:49:51
    edn区、s0、s1都属于新生代,tentired属于老年代。s指survivor。 对象会在eden区分配内存,在经历一次新生代垃圾回收后,如果对象还存活,则进入s0或者s1,并且对象的年龄会加1。当年龄增加到一定程度(默认15岁,...
  • JVM 新生代老年代与GC

    千次阅读 2019-08-06 21:57:51
    Java堆可以分为新生代和老年代两个区,其中新生代又可以分为一个Eden区和两个Survivor区,两个Survivor区分别被命名为From和To以示区分,新生代和老年代的比例为1:2,它们共同组成堆的内存区,所以新生代占堆的1/3...
  • java新生代和老年代

    千次阅读 2019-03-31 23:14:04
    堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。 这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的...
  • 对象如何进入老年代

    千次阅读 2019-05-11 09:57:42
    问题:一般而言,对象首次创建会被放置在...1:大对象直接进入老年代。比如很长的字符串,或者很大的数组等,参数-XX:PretenureSizeThreshold=3145728设置,超过这个参数设置的值就直接进入老年代 2:长期存活的对...
  • jvm 新生代、老年代

    2017-07-27 14:40:12
    在JAVA中堆被分为两块区域:新生代(young)、老年代(old)。 堆大小=新生代+老年代;(新生代占堆空间的1/3、老年代占堆空间2/3) 新生代又被分为了eden、from survivor、to survivor(8:1:1); 新生代这样...
  • JVM老年代垃圾回收Full GC

    千次阅读 2020-08-07 13:53:56
    老年代GC:FullGC 是老年代的GC,在新生代如果说存在的对象或者说新创建 出来的对象由于某些原因需要移动到老年代中,但是老年代中压根就没有这么大的内存空间去容纳这个对象, 那么就会引发一次FullGC,如果在执行...
  • Major GC 是清理老年代。 Full GC 是清理整个堆空间—包括年轻代和老年代
  • 这篇文章我们接着之前的案例继续来做实验,动手体验一下对象是如何从新生代进入老年代的。 动态年龄判定规则 之前我们给大家总结过对象进入老年代的4个常见的时机: 躲过15次gc,达到15岁高龄之后进入老年代; ...
  • 首相明确一点,年轻代和老年代属于堆;永久代属于在Hotspot虚拟机下对方法区的实现,并不存在于堆中。   在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old)。新生代 ( Young ,垃圾回收器...
  • JVM触发老年代GC的情景收集 当老年代可用内存小于新生代对象总大小时,根据是否开启了允许空间担保失败,决定是否进行Full GC 相关参数:HandlePromotionFailure 如果设置HandlePromotionFailure = true了,那么...
  • 1.大对象(字符串与数组),是指需要大量连续内存空间的java对象,比如字符串和数组。即超过了设定值的对象,直接在老年代中分配。 2.长期存活的对象可以从年轻代进入老年代。 ...
  • 老年代的垃圾回收 什么情况下对象会进入到老年代 在JVM中,每个对象都有一个GC年龄,当发生GC时,如果对象没有被回收,那么它的GC年龄就+1 默认情况下,GC年龄超过15的对象会进入老年代,如果想自定义这个年龄可以...
  • 新生代中的复制算法会从Eden区将对象复制到survivor区,那对象晋升到老年代是通过什么方式呢?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 124,709
精华内容 49,883
关键字:

老年代