一、对象何时进入老年代

(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. Fortran一个获取硬件系统信息的函数库

    此函数库提供了 Visual Fortran 上获取硬盘ID,CPU编号,windows安装时间及文件头部校验的四个函数.可用于简单的程序加密.(但切勿用于商业性很强的地方)              ...

  2. [转]:Delphi XE中泛型数组的使用范例

    Delphi XE中泛型数组的使用范例,下面的范例简单的使用了泛型字符串数组,如用 TArray 代替 array of Word, 还可以使用 TArray 类提供的算法(就是少了点). uses ...

  3. Sublime Text 文件路径补全

    最有效和好用的是AutoFileName插件,效果如下: 表格编辑 Table Editor相当好用,安装好后参考自述文件(Preferences --> Package Settings -- ...

  4. Win10 15063 开始运行不保存历史记录原因和解决方法

    http://www.ampc8.com/thread-23421-1-1.html 在Win10 1703的时候你也许会发现开始运行以后,再次打开就没有任何历史记录了,常规方法是桌面-右键-个性化- ...

  5. xorm中的几个坑

    项目中使用的是xorm,虽然用了很顺手了,可是还是会遇到一些坑,这里纪录一些. 结构体自动忽略空字段 在xorm中,结构体会自动忽略空字段(或则说默认值,比如int 的0 ,string的" ...

  6. Linux零基础入门第四课

    根据直播讲义整理的内容,从第四课开始.前三课的内容若后面有精力会一并整理进来. 文件的基本操作(上) 创建.删除.复制.移动和重命名 touch命令创建文件 语法 >$ touch file0 ...

  7. Vue.js之Vue计算属性、侦听器、样式绑定

    前言 上一篇介绍了Vue的基本概念,这一篇介绍一下Vue的基本使用. 一.搭建一个Vue程序 1.1 搭建Vue环境 搭建Vue的开发环境总共有三种方法: 引入CDN <script src=& ...

  8. 目前我对ReactNative的了解

    1.什么是React? 一个js组件库,不同于angular的是一个完整的framework,React需要像jQuery一样写事件监听逻辑,最大特点是Virtual DOM. 官网:https:// ...

  9. iOS开发之--在UIWindow上展示/移除一个View

    代码如下: 展示 UIWindow *window = [[UIApplication sharedApplication].windows lastObject]; [window addSubvi ...

  10. java相对路径、绝对路径及类路径

    import java.io.File; import java.net.URL; /** * java相对路径.绝对路径及类路径的测试 */ public class Test { /** * 测试 ...