一、对象何时进入老年代

(1)当对象首次创建时, 会放在新生代的eden区, 若没有GC的介入,会一直在eden区, GC后,是可能进入survivor区或者年老代

(2)当对象年龄达到一定的大小 ,就会离开年轻代, 进入老年代。 而对象的年龄是由GC的次数决定的

-XX:MaxTenuringThreshold=n  新生代的对象最多经历n次GC, 就能晋升到老年代, 但不是必要条件   

-XX:TargetSurvivorRatio=n  用于设置Survivor区的目标使用率,即当survivor区GC后使用率超过这个值, 就可能会使用较小的年龄作为晋升年龄

(3)除年龄外, 对象体积也会影响对象的晋升的, 若对象体积太大, 新生代无法容纳这个对象

-XX:PretenureSizeThreshold  即对象的大小大于此值, 就会绕过新生代, 直接在老年代分配, 此参数只对串行回收器以及ParNew回收有效, 而对ParallelGC回收器无效

二、何时发生full gc

public class ConcurrentMarkSweep {

    private static final int SIZE= 1024 * 1024;

    public static void main(String[] args) throws Exception{
byte[] a1, a2, a3, a4;
a1 = new byte[2 * SIZE];
a2 = new byte[2 * SIZE];
a3 = new byte[2 * SIZE];
a4 = new byte[2 * SIZE];
System.in.read();
}
}

1. System.gc()方法的调用 
system.gc(), 此方法的调用是建议JVM进行Full GC, 可通过通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc。

2. old/Tenured 空间不足

老年代空间在新生代对象转入及创建为大对象、大数组时

当执行Full GC后空间仍然不足,报错:java.lang.OutOfMemoryError: Java heap space

java -Xmx10m -Xms10m -Xmn10m -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=75 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC gc.ConcurrentMarkSweep

3. perm/metaspace 空间不足

JVM规范中运行时数据区域中的方法区,在HotSpot虚拟机中又被习惯称为永生代或者永生区,

Permanet Generation中存放的为一些class的信息、常量、静态变量等数据,当系统中要加载的类、反射的类和调用的方法较多时,

当Full GC后空间仍然不足,报错:java.lang.OutOfMemoryError: PermGen space

java -cp .:/Users/gl/IntelliJProjects/JBase/jdk/build/tmp/lib/javassist-3.20.0-GA.jar  -XX:MaxMetaspaceSize=32M gc.Metaspace
在我的MAC上,大约生成21165个class: Exception in thread "main" javassist.CannotCompileException: by java.lang.OutOfMemoryError: Metaspace
public class Metaspace {

   static  ClassPool cp = ClassPool.getDefault();

    public static void main(String[] args) throws Exception{
for (int i = 0; ; i++) {
System.out.println(i);
CtClass ctClass = cp.makeClass("com.mp.Person" + i );
//添加属性
ctClass.addField(CtField.make("private int age;", ctClass));
//添加setAge方法
ctClass.addMethod(CtMethod.make("public void setAge(int age){this.age = age;}", ctClass));
ctClass.addMethod(CtMethod.make("public int getAge(){return this.age;}", ctClass));
//If the program is running on some application server, the context class loader might be inappropriate to load the class.
//如果没有调用,则没影响
ctClass.toClass();
}
}
}

4. CMS GC时出现promotion failed和concurrent mode failure

promotion failed是在进行Minor GC时,survivor space放不下, 对象只能放入老年代,而此时老年代也放不下造成的;

concurrent mode failure是在执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间不足造成的

java -Xmx10m -Xms10m -Xmn10m -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=75 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC gc.ConcurrentMarkSweep

5. 判断当前新生代的对象是否能够全部顺利的晋升到老年代,如果不能,就提早触发一次老年代的收集

java -Xmx14m -Xms14m -Xmn10m -XX:+UseParNewGC  -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly  -XX:CMSInitiatingOccupancyFraction=75 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC ConcurrentMarkSweep

# JVM 通过 CMSInitiatingOccupancyFraction 的值确定是否gc
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75

如下,Meta space 使用为达到75%, 却一直在发生FGC

如果永久代设置的很小,则会发生系统刚启动就执行CMS

参考:

占小狼:一个有意思的CMS问题

对象何时进入老年代、何时发生full gc的更多相关文章

  1. java中什么样的对象能够进入老年代

    1.大对象:所谓的大对象是指需要大量连续内存空间的java对象,最典型的大对象就是那种很长的字符串以及数组,大对象对虚拟机的内存分配就是坏消息,尤其是一些朝生夕灭的短命大对象,写程序时应避免. 2.长 ...

  2. 深入理解Java虚拟机(第二版)中《长期存活对象将进入老年代》的实践

  3. 关于gc日志中Desired Survivor的疑问和对象晋升老年代的小结

    问题背景 (下面的所有内容都是根据书上的Serial/Serial Old收集器下的情况) 在<深入理解JVM>一书中的——3.6.3长期存活的对象将进入老年代的介绍中, 一个例子的jvm ...

  4. 实验: survivor放不下的对象进入老年代

    实验一: 存活对象包含 小于survivor大小的对象 + 大于survivor的对象 private static final Integer _1MB = 1024 * 1024; /** * - ...

  5. JVM之堆内存(年经代,老年代)

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

  6. JVM内存:年轻代、老年代、永久代(推荐 转)

    参考文章: 1.Java 新生代.老年代.持久代.元空间 2.Java内存与垃圾回收调优 3.方法区的Class信息,又称为永久代,是否属于Java堆? Java 中的堆是 JVM 所管理的最大的一块 ...

  7. 什么是新生代 GC 和老年代 GC

    GC 经常发生的区域是堆区,堆区还可以细分为新生代.老年代 jvm堆示意图 新生代 一个 Eden 区 两个 Survivor 区 老年代 默认 新生代(Young)与老年代(Old)的比例的值为 1 ...

  8. JVM学习八-(复习)年轻代、老年代、永久代

    Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象,如下图所示: 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old).新生代 ...

  9. 【转】Java中的新生代、老年代、永久代和各种GC

    JVM中的堆,一般分为三大部分:新生代.老年代.永久代: 1 新生代 主要是用来存放新生的对象.一般占据堆的1/3空间.由于频繁创建对象,所以新生代会频繁触发MinorGC进行垃圾回收. 新生代又分为 ...

随机推荐

  1. Fedora 25-64位操作系统中安装配置Hyperledger Fabric过程

    安装过程参照Hyperledger Fabric的官方文档,文档地址:http://hyperledger-fabric.readthedocs.io/en/latest/prereqs.html 0 ...

  2. 二叉树遍历-c实现

    这里主要是三种遍历,先序(preorder,NLR),中序(Inorder,LNR),后序(Postorder,LRN) N:node,L:left,R:right 基本排序:先序(NLR,节点,左, ...

  3. webview调起浏览器

    调起浏览器 url = "intent://" + url +"#Intent;scheme=http;action=android.intent.action.VIEW ...

  4. 【温暖】文龙回AICODER给老马送锦旗了

    又是一个愉快的周末,AICODER第一批老学员文龙小伙伴.已经工作两个月,而且就业薪资12000+,文龙从之前月薪不足4000,一下子翻了三倍多的工资. 几个月的实习,让文龙掌握了大前端全栈的技术,在 ...

  5. WOW.js和animate.css让页面滚动时显示动画

    官网:http://mynameismatthieu.com/WOW/ bootstrap CDN服务:http://www.bootcdn.cn/wow/ 1.wow.js 实现了在网页滚动时的动画 ...

  6. golang处理signal

    signal一般用来实现优雅重启,或者重新加载配置文件等操作. 废话不多说,上表格 动作 号码 信号 golang kill pid 15 SIGTERM terminated kill -9 pid ...

  7. SAP Parallel Accounting(平行分类账)业务配置及操作手册

    目录 SAP Parallel Accounting(平行分类账业务)配置及操作手册 SAP Parallel Accounting(平行分类账业务)配置及操作手册 Overview 业务说明 为了适 ...

  8. WebSphere MQ中的CCSID

    CCSID是一个字符集的标识.作为unicode标准通过定义一个字符集内每个字符要对应那个数字值的方式定义了一个字符集.这说明CCSID就是一个定义字符集顺序的标识数码罢了.IBM的字符标识架构在文档 ...

  9. etl数据同步工具 kettle

    kellet使用 https://www.cnblogs.com/gala1021/p/7814712.html

  10. Linux下常见命令

    =============挂载和登陆命令======================================== Mount:挂载命令. 比方挂载光驱mount /dev/cdrom /mnt ...