1、前文回顾

略..

2、动态年龄判定规则

进入老年代的4个时机:1、年龄到了 2、动态年龄判断 3、Survivor 放不下 4、大对象(G1例外)

动态年龄判断:Young GC时,新对象(1岁)进入S区,如果Survivor区域内“年龄1+年龄2+...+年龄n”的对象总和大于Survivor区的50%,此时年龄n以上的对象会进入老年代。

新生代分配了10M,Eden 8M,From 1M ,To 1M

3、动态年龄判定规则的部分示例代码

-XX:NewSize=10485760-XX:MaxNewSize=10485760-XX:InitialHeapSize=20971520-XX:MaxHeapSize=20971520-XX:SurvivorRatio=8-XX:MaxTenuringThreshold=15-XX:PretenureSizeThreshold=10485760-XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:d:/gc.log
public class _44ToOldGC {static List<byte[]> longActiveList = new ArrayList<>();//长期存活static final int M = 1024 * 1024;static final int K = 1024;public static void main(String[] args) throws InterruptedException {System.gc();//先清除堆中的垃圾对象,否则后面的数值大小令人费解。不过运行过程中还是有额外的小空间多出来/*** 堆 20M* 新生代 10M (Eden 8M,From 1M ,To 1M)* 老年代 10M*/allocate(2*M);allocate(2*M);allocate(2*M);addLongActiveObj(128*K);allocate(2*M);//此处触发YoungGC}private static void allocate(int size) {byte[] bytes = new byte[size];}private static void addLongActiveObj(int size){longActiveList.add(new byte[size]);}}

4、部分示例代码运行后产生的gc日志

0.133: [Full GC (System.gc()) 0.133: [CMS: 0K->726K(10240K), 0.0033735 secs] 2230K->726K(19456K), [Metaspace: 3361K->3361K(1056768K)], 0.0034877 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.138: [GC (Allocation Failure) 0.138: [ParNew: 6473K->192K(9216K), 0.0006125 secs] 7200K->918K(19456K), 0.0006481 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]Heappar new generation   total 9216K, used 2404K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,  27% used [0x00000000fec00000, 0x00000000fee29280, 0x00000000ff400000)from space 1024K,  18% used [0x00000000ff500000, 0x00000000ff530010, 0x00000000ff600000)to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)concurrent mark-sweep generation total 10240K, used 726K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)Metaspace       used 3438K, capacity 4500K, committed 4864K, reserved 1056768Kclass space    used 374K, capacity 388K, committed 512K, reserved 1048576K

解读:

[CMS: 0K->726K(10240K), 0.0033735 secs] 2230K->726K(19456K)

0K->726K :有726K 晋升到老年代

2230K->726K(19456K):堆中2230K(老年代0,新生代2230),堆中回收后就剩晋升到老年代的726K

ParNew: 6473K->192K(9216K):6473(多个byte数组+未知对象),192K(128K的byte数组+未知存活对象)

allocate(2*M);allocate(2*M);allocate(2*M);addLongActiveObj(128*K);allocate(2*M);//此处触发YoungGC

第五行代码触发了Young GC, 前三行代码分配的对象和其他一些未知对象被回收 ,回收后剩余192K

5、部分代码的GC日志分析

见 4

6、动态年龄判断

将addLongActiveObj(128*K);改为addLongActiveObj(513*K); 使长期存活的占了From区的一半多一点点

然后在加入四行

allocate(2*M);allocate(2*M);allocate(2*M);allocate(2*M);
0.140: [GC (Allocation Failure) 0.140: [ParNew: 6984K->577K(9216K), 0.0005920 secs] 7703K->1295K(19456K), 0.0006294 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.141: [GC (Allocation Failure) 0.141: [ParNew: 6939K->4K(9216K), 0.0006386 secs] 7658K->1257K(19456K), 0.0006760 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

执行第四行时,触发YoungGC, 这次Young GC 没有Eden区的对象存活,此时Survivor区的存活对象年龄+1 变为2岁,一批同龄对象,直接超过了Survivor区空间的50%,此时也可能会导致对象进入老年代。

??按照文中的动态年龄判断逻辑不是应该“大于2岁”的对象进入老年代么? 如果按照专栏25讲描述的动态年龄判断逻辑倒是可以解释的通(一批同龄对象,直接超过了Survivor区空间的50%,此时也可能会导致对象进入老年代)

答:对的,他就是同龄对象超过了Survivor的50%,所以进入老年代了

PS:

1、如果直接allocate(8*M),真正的大小比8M多一点点,Eden区肯定是放不下的,虽然没满足设置的大对象10M的要求,连YoungGC都不触发,直接进入老年代

2、如果直接allocate(7*M+1000*K); 会回收两次,第一次放入时判断Eden放不下,触发YoungGC,回收之前allocate(2*M);放入的对象,放入后,可能系统又放了对象进来,有触发了一次 allocate(7*M+1000*K)被回收了

7、分析最终版的GC日志

见6

8、今日思考题

代码模拟出来对象达到5岁年龄之后自然进入老年代的场景

public static void maxTenuringTest() {for(int i=0;i<10;i++){allocate(4 * M);longActiveList.add(new byte[32*K]);}}

GC日志:

0.137: [GC (Allocation Failure) 0.137: [ParNew: 4423K->80K(9216K), 0.0006453 secs] 5141K->797K(19456K), 0.0006869 secs] [Times: user=0.03 sys=0.00, real=0.00 secs]0.138: [GC (Allocation Failure) 0.138: [ParNew: 4373K->78K(9216K), 0.0003029 secs] 5091K->795K(19456K), 0.0003315 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.139: [GC (Allocation Failure) 0.139: [ParNew: 4371K->108K(9216K), 0.0004725 secs] 5089K->825K(19456K), 0.0005057 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.140: [GC (Allocation Failure) 0.140: [ParNew: 4398K->140K(9216K), 0.0002472 secs] 5116K->858K(19456K), 0.0002849 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.140: [GC (Allocation Failure) 0.140: [ParNew: 4429K->178K(9216K), 0.0003791 secs] 5147K->896K(19456K), 0.0004119 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.141: [GC (Allocation Failure) 0.141: [ParNew: 4466K->176K(9216K), 0.0004767 secs] 5184K->944K(19456K), 0.0005208 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.142: [GC (Allocation Failure) 0.142: [ParNew: 4463K->174K(9216K), 0.0003166 secs] 5232K->975K(19456K), 0.0003466 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.143: [GC (Allocation Failure) 0.143: [ParNew: 4460K->168K(9216K), 0.0004341 secs] 5262K->1002K(19456K), 0.0004739 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]0.144: [GC (Allocation Failure) 0.144: [ParNew: 4454K->172K(9216K), 0.0003660 secs] 5288K->1038K(19456K), 0.0004041 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

maxTenuringTest方法,循环第二次 allocate(4 * M);开始,会不断触发YoungGC,第六次开始,Survivor 区维持在174K左右,但堆的剩余在不断的增长,如下图。主要是因为每次有一个新的进入S区,就有一个年龄大的晋升到老年代。

本文是《从 0 开始带你成为JVM实战高手》内容总结,版权问题,特此声明。详细内容:

如果购买,成功后加QQ群找群主返现10元

045、JVM实战总结:动手实验:自己动手模拟出对象进入老年代的场景体验一下(上)相关推荐

  1. 046、JVM实战总结:动手实验:自己动手模拟出对象进入老年代的场景体验一下(下)

    本文是<从 0 开始带你成为JVM实战高手>内容总结,版权问题,特此声明.详细内容: 如果购买,成功后加QQ群找群主返现10元

  2. jvm性能调优实战 - 24模拟因动态年龄判断对象进入老年代的场景

    文章目录 Pre 动态年龄判定规则 动态年龄判定规则的部分示例代码 部分示例代码运行后产生的gc日志 完善示例代码 GC日志分析 Pre 上一篇文章我们已经带着大家初步分析了一次Young GC的日志 ...

  3. JVM 年轻代(Eden、From、To)、老年代讲解

    概述 JVM 的堆空间分成2个区域:年轻代.老年代 年轻代又进一步细分成3个区域:Eden.Survivor From.Survivor To 如下图所示: 默认情况下,年轻代与老年代比例为1:2.可 ...

  4. JVM中对象进入老年代的3种情况

    1. 对象年龄达到阈值后进入老年代 默认情况下,对象在新生代经历了15次GC后,便会达到进入老年代的条件,将对象转移进入老年代.当然,年龄的阈值可以通过JVM参数进行设置: -XX:MaxTenuri ...

  5. JVM调优:对象进入老年代的两个条件

  6. .NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(上)

    06 | 作用域与对象释放行为 作用域主要由 IServiceScope 这个接口来承载 对于实现 IDisposable 类的实例的对象,容器会负责对其生命周期进行管理,使用完毕之后,他会释放这些对 ...

  7. 050、JVM实战总结:动手实验:使用 jstat 摸清线上系统的JVM运行状况

    jstat详细信息,参考:jstat - Java Virtual Machine Statistics Monitoring Tool 1.前文回顾 对象优先在Eden区分配,Young GC的触发 ...

  8. Win2008 R2 VDI动手实验系列之一:Active Directory搭建

    Win2008 R2 VDI动手实验系列之一:Active Directory搭建 2010-03-22 23:54:45 标签:动手实验 VDI R2 休闲 Win2008 原创作品,允许转载,转载 ...

  9. 052、JVM实战总结:从测试到上线:如何分析JVM运行状况及合理优化?

    恭喜大家:学到现在,其实大家可以尝试自己写一个JVM监控程序了(对学习扎实的同学没什么难度的,就是工作量的问题),然后用监控的数据,根据学到的优化思路,给出合理的参数建议.写好了投入生产使用,后续绝对 ...

最新文章

  1. Activity采用栈式管理的理解
  2. 利用矩阵快速幂求斐波那契数列
  3. lcd刷新慢_LCD1602刷新率很慢的问题
  4. 如何解决vuepress部署出现样式问题
  5. Java之一致性hash算法原理及实现
  6. SAP License:GL显示行项目
  7. @程序员们,华为员工 300 万分红,老板给你多少年终奖?
  8. thymeleaf th:href 多个参数传递格式
  9. bzoj 4002: [JLOI2015]有意义的字符串(特征根法+矩阵快速幂)
  10. poj 3264 Balanced Lineup RMQ问题
  11. java 排序返回索引_java数组排序和索引
  12. 安卓耳机左右音量调节_安卓/IOS系统通用耳机调音PCBA 按键调节音量 一键转换三星苹果...
  13. 面试计算机有什么优势和不足,面试时如何介绍自己的优缺点
  14. CATIA达索三维建模软件的功能和核心技术是什么?
  15. python中类的self到底是什么
  16. IDEA中scala安装与配置(详细步骤)
  17. 【java网络编程】TCP三次握手、四次挥手,常见Socket通信BIO
  18. 鸿蒙见面会为什么没选在深圳,全军出击!华为智选发布16款新品:鸿蒙分布式技术来了近日,华...
  19. 四类运算放大器的技术发展趋势及其应用热点
  20. Hands on Machine_Learning with Scikit-LearnTensorFlow 资源下载

热门文章

  1. [Web Chart系列之三] 图形布局-Layout
  2. Oracle 用户信息查询,操作语句
  3. http server类型和版本号_nginx 简单隐藏服务器版本号
  4. java web 部署图片_java web项目 图片资源与部署目录分离,设置服务器的虚拟路径...
  5. 怎么把video文件改成mp4_GiliSoft Video Converter将MP4视频转换成M4V格式教程
  6. 分页查询为什么会报数组越界错误_Java Note-数据结构(1)数组
  7. Spring Cloud 启动Eureka的Client(客户端)时,项目一启动就停止,控制台无任何报错信息
  8. 根据数字生成唯一数字_PLSQL——根据上下数字生成等差数列补充空白行
  9. 转一个高内存定位的文章
  10. Command line is too long. Shorten command line for Doc.generateAsciiDocs or