什么样的垃圾会进入到老年代?对象进入老年代的条件有三个,满足一个就会进入到老年代,
- 1、躲过15次GC。每次垃圾回收后,存活的对象的年龄就会加1,累计加到15次(jdk8默认的),也就是某个对象躲过了15次垃圾回收,那么JVM就认为这个是经常被使用的对象,就没必要再带着年轻代中了。具体的次数可以通过 -XX:MaxTenuringThreshold 来设置在躲过多少次垃圾收集后进去老年代。
- 2、动态对象年龄判断。规则:在某个 Survivor 中,如果有一批对象的大小总是大于该 Survivor 的 50%,那么此时大于等于该批对象年龄的对象机会会直接到老年代中。
- 3、大对象直接进入老年代。-XX:PretenureSizeThreshold 来设置大对象的临界值,大于该值的就被认为是大对象,就会直接进入老年代。
针对上面的三点来逐一分析:
躲过15次 GC
这个没啥好说的,最好理解,就是在执行了15次GC后,对象依旧存活,那么就将其移动到老年代中去,没执行一次垃圾回收,存活的对象的年龄就+1,具体的执行次数可以通过:-XX:PretenureSizeThreshold
参数来设置。
动态对象年龄判断
这就有点难理解了,不过在我 xx 面前,就一定会给你讲清楚。
再来看下这个规则:在某个 Survivor 中,如果有一批对象的大小总是大于该 Survivor 的 50%,那么此时大于等于该批对象年龄的对象机会会直接到老年代中。
o(╥﹏╥)o 还是没理解。。。我们画图来理解试试
假设现在 To 里面的如图两个对象大小总和50 M,且都是3岁了,因为 To 是100 M,所以这个时候我们就说在某个 Survivor 中,如果有一批对象的大小总是大于该Survivor 的 50%。这个时候大于等于该批对象年龄的对象机会会直接到老年代中。
再还换句话说就是:当前放对象的Survivor区域里(其中一块区域,放对象的那块s区),一批对象的总大小大于这块Survivor区域内存大小的50%(-XX:TargetSurvivor 修可以指定),那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代了。
例如Survivor区域里现在有一比对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了的多个年龄对象总和超过了区域的50%,此时就会巴年龄n(含)以上的对象都放入老年代)。这个规则其实是希望那些可能是长期存活的对象,尽早进入老年代。对象动态年龄判断机制一般是在 Minor GC 之后触发的。
大对象直接进入老年代
这个就简单了,-XX:PretenureSizeThreshold 来设置大对象的临界值。如 -XX:PretenureSizeThreshold=1024 * 1024。即对象超过1M直接进入老年代。其实大对象直接进入到老年代还包含这种情况:那就是当 Eden 中执行了 Minor GC 后,存活的对象的大小是 超过了100M了(上图 from 和 to 都是100M)此时这些存活的对象也是直接进入到老年代。
说了半天对象都跑到老年代去了,那既然老年代这个牛逼,干嘛还分年轻代和老年代?年轻人,你不要急。后文我会全部道来。我们下面先来看看老年代空间如果不够用怎么办?
转载:https://blog.csdn.net/hollis_chuang/article/details/117001607