一、对象何时进入老年代

(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. [转]MySQL中timestamp数据类型的特点

    原文地址:https://www.imooc.com/article/16158 在使用MySQL数据库时有很多常见的误解,其中使用int类型来保存日期数据会提高数据读取的效率就是比较常见的一个误解. ...

  2. spring相关面试题

    1.spring有依赖的bean,怎么加载? 2.spring怎么解决循环依赖? https://blog.csdn.net/u010853261/article/details/77940767 h ...

  3. Unity游戏推送技术

    https://www.cnblogs.com/wuzhang/p/wuzhang20150401.html https://www.cnblogs.com/yangwujun/p/5789969.h ...

  4. IntelliJ IDEA License Server 安装使用 Mac篇

    一.下载 IntelliJ IDEA 是Java开发利器,用社区版不爽,干催就用旗舰版,这个是收费的,需要licence.  IntelliJ IDEA下载地址:https://www.jetbrai ...

  5. 搭建Pypi转发服务

    有时候有些正式环境的机器,不能访问外网,就只能在能访问外网的机器上搭建一个转发服务. 一.安装包 pip install flask_pypi_proxy flask_pypi_proxy 二.启动 ...

  6. 基于ARM9和嵌入式Linux系统的多功能综合通信控制系统的框架

    基于ARM9硬件平台和嵌入式Linux系统的多功能综合通信控制系统的框架设计及各模块的功能.系统采用符合POSIX.1标准的C语言编写,实现了对下位机传送数据帧的采集.分析和存储,并能根据上位机的配置 ...

  7. 《转载》JVM垃圾回收机制

    本文转载自ImportNew - 郑雯 每个Java程序员迟早都会碰到下面这个错误: java.lang.OutOfMemoryError 这个时候一般会建议采用如下方式解决这个错误: 增加MaxPe ...

  8. Spring Security http标签的use-expressions="true"属性

    如果声明为true,那么在access属性要用hasRole()这样写: <intercept-url pattern="/secure/extreme/**" access ...

  9. pyqt4手动编写资源文件

    资源文件resource.qrc为XML格式,格式较简单,可以手动编辑: <!DOCTYPE RCC><RCC version="1.0"> <qre ...

  10. 使用TensorFlow构建自己的网络

    TensorFlow对我来说,是一个陌生的框架,又很复杂,学起来不是很容易,需要找到合适的方法. 今天从tf.zeros入手,这个函数最简单,但是知道它的源码在哪里吗?后来我发现github上也有很多 ...