一、对象何时进入老年代

(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. What’s new for Spark SQL in Apache Spark 1.3(中英双语)

    文章标题 What’s new for Spark SQL in Apache Spark 1.3 作者介绍 Michael Armbrust 文章正文 The Apache Spark 1.3 re ...

  2. 企业级镜像仓库Harbor

    介绍: Habor是由VMWare公司开源的容器镜像仓库.事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面, ...

  3. Spring Boot项目的接口防刷

    说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springboot的基本知识,redis基本操作, 首先是写一个注解类: import java.lang.an ...

  4. 8款基于Jquery的WEB前端动画特效

    1.超炫酷的30个jQuery按钮悬停动画 按钮插件是最常见的jQuery插件之一,因为它用途广泛,而且配置起来最为方便.今天我们要分享的是30个超炫酷的jQuery悬停按钮动画,当我们将鼠标滑过按钮 ...

  5. 在interface vlan下敲no ip proxy-arp什么意思

    取消由路由带来的ARP请求. proxy ARP有哪些优点? 最主要的一个优点就是能够在不影响其他router的路由表的情况下在网络上添加一个新的router,这样使得子网的变化对主机是透明的 pro ...

  6. Java编程的逻辑 (93) - 函数式数据处理 (下)

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  7. python 读取mysql数据至csv文件中,并发送邮件

    test 代码: #coding:utf-8 ''' Created on 2019年2月18日 @author: Administrator ''' import ConfigParser impo ...

  8. elasticsearch以及head插件在centos7上的安装与配置教程

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

  9. javascript:没有定义的变量和没有定义的属性

    1. 没有定义的变量 window.onload = function() { alert(a); // 报错: Uncaught ReferenceError: a is not defined / ...

  10. java发送邮件无法显示图片 图裂 的解决办法

    package com.thinkgem.jeesite.common.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; ...