调整JVM参数如下:

-XX:NewSize=104857600—新生代大小为100m
-XX:MaxNewSize=104857600—新生代最大大小为100m
-Xms200M—初始堆大小为200m
-Xmx200M—最大堆大小为200m
-XX:+UseParNewGC:新生代使用ParNewGC垃圾回收器
-XX:+UseConcMarkSweepGC---老年代使用CMS
-XX:+PrintGCDetails---打印GC详细日志
-XX:+PrintGCTimeStamps—打印GC时间
-XX:SurvivorRatio=8—设置eden区和survivor区的比例为8:1:1
-XX:PretenureSizeThreshold=209715200—设置最大对象的阈值为20m

测试demo

package com.example.springboot.jvm;import java.util.concurrent.TimeUnit;public class 年轻代gc耗时真的比老年代短 {public static void loadData() throws InterruptedException {byte[] data = null;for (int i = 0; i < 4; i++) {//每个请求10mdata = new byte[10 * 1024 * 1024];}data = null;byte[] data1 = new byte[10 * 1024 * 1024];byte[] data2 = new byte[10 * 1024 * 1024];byte[] data3 = new byte[10 * 1024 * 1024];data3 = new byte[10 * 1024 * 1024];//睡眠1秒TimeUnit.SECONDS.sleep(1);}public static void main(String[] args) throws InterruptedException {//这里睡眠20秒是为了能够有足够的时间打命令,看到的效果可以更直观TimeUnit.SECONDS.sleep(20);while (true) {loadData();}}
}

启动服务,进入命令行界面。

先输入命令jps,查看各个进程,结果如下:


从结果中可以得到启动程序对应的进程号为3222。

输入命令jstat -gc 3222 1000 1000,表示统计进程3222的JVM运行状态,然后每隔一秒钟打印统计信息,持续打印1000次,结果如下:


可以发现EU列(Eden区)每次大概增加10M左右的对象,OU列(老年代)每次大概新增20~30M左右的对象,同时每秒触发一次新生代GC,老年代大致每3秒一次GC,不过此时的YGCT(年轻代GC总耗时)远远大于FGCT(老年代GC总耗时),即使双方各除以他们的总次数YGC(年轻代GC总次数)或者FGC(老年代GC总次数),年轻代GC的平均耗时也远远大于老年代GC的耗时。

这里先解释下为什么Eden区每次大概增加10M左右的对象,老年代每次大概新增20~30M左右的对象?

首先堆的大小设置为200,新生代的大小被设置为100M,同时Eden区和两个Survivor区的比例是8:1:1,那么Eden区的大小就是80M,两个Survivor区各为10M,老年代的大小为100M。

回顾代码,每秒会新建40M左右的对象,然后立马置空,让这40M对象失去引用变成垃圾对象,接着继续新建了data1,data2,data3三个对象,每个对象大小各为10M,这时候Eden区就被占用了大致70M左右的空间,最后又将data3变量引用指向另一个10M对象,此时Eden区空间已经不够分配这10M对象了,所以会触发新生代GC,此时40M垃圾对象会被回收,但是data1,data2,data3这三个变量的引用还是有效的,所以GC后一共有30M左右的对象存活,而Survivor区只有10M大小,是放不下30M对象的,因此这30M对象会直接被分配到老年代,然后再分配data3变量最后引用的10M对象,所以每秒Eden区会被占用10M空间。

为什么此时的年轻代gc耗时比老年代长?

一般来说,在固有的印象里,年轻代gc耗时比老年代要短得多,真正影响系统性能的应该是老年代GC产生的STW时间,但是在该示例中,年轻代的gc耗时比老年代要长,这是因为,老年代每次会新增20~30M左右的对象,新生代GC后的存活对象有30M左右,老年代空间放不下时,就会触发Full GC,腾出空间后,等到存活对象进入老年代了,新生代GC才算结束。因此可以理解成,本次的新生代GC时间其实是叠加了老年代GC时间的,所以新生代gc耗时才会比老年代长。

总结

如果每次年轻代GC时,都会触发老年代GC,那么年轻代GC耗时就会比老年代长了。

年轻代gc耗时真的比老年代短?相关推荐

  1. jvm之年轻代(新生代)、老年代、永久代以及GC原理详解

    关于JVM,也许你听过这些术语:年轻代(新生代).老年代.永久代.minor gc(young gc).major gc.full gc 不要急,先上图,这是jvm 堆内存结构图 仔细的你发现了 图中 ...

  2. java年轻代minor gc_jvm之年轻代(新生代)、老年代、永久代以及GC原理详解、GC优化...

    关于JVM,也许你听过这些术语:年轻代(新生代).老年代.永久代.minor gc(young gc).major gc.full gc 不要急,先上图,这是jvm 堆内存结构图 仔细的你发现了 图中 ...

  3. JVM年轻代(young generation)老年代(old generation tenured)持久代(permanent generation)GC...

    关于jvm内存代,看到这篇文章,转发下 链接地址 ---多谢 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent ...

  4. JVM年轻代(young generation)老年代(old generation tenured)持久代(permanent generation)GC

    关于jvm内存代,看到这篇文章,转发下 链接地址 ---多谢 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent ...

  5. Java GC、新生代、老年代、gc日志分析

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

  6. Java 年轻代GC

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

  7. JVM内存中的年轻代,老年代

    引言 对于大多数Java应用来说,Java Heap(Java堆)是JVM管理的内存中较大的一块,而且Java Heap是被所有线程共享的一块内存区域,于虚拟机启动时创建. 而Java堆的唯一目的就是 ...

  8. 深入jvm之对象如何进入老年代

    简介 我们知道,整个jvm堆分为新生代和老年代,新生代的对象在进行垃圾回收的时候,可能会进入到老年代,那么我们知道年轻代的对象是如何进入到老年代的吗? 年轻代空间分配 新生代分成Eden,Surviv ...

  9. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

最新文章

  1. 微信小程序点餐+SpringBoot(包括后台)
  2. 第十六届全国大学生智能车竞赛线上比赛-赛前开题
  3. 专家预测第二波WannaCry勒索病毒攻击即将到来!
  4. 260多媒体语言如何调节_260马力配9.7米货厢,实拍柳汽H5小三轴载货车
  5. e_msg_c_gs_enter_gs_req
  6. 完整的python项目实例-Python实例练手项目汇总(附源码)
  7. Java开发人员可以从Spring框架中学到编程技巧
  8. PHP使用PHPExcel删除Excel单元格指定列的方法
  9. 英文名大全及含义(男)
  10. eureka多台注册中心_spring cloud eureka集群,注册中心再添加一台服务器
  11. 上传大文件报错413问题处理
  12. LayoutInflater.inflate()方法的深入理解
  13. java spider爬虫_一个简单的java网络爬虫(spider)
  14. 程序员:你30岁前的职业规划是什么?未来的职业规划又是什么?
  15. SIGMOD 2020 CockRoach 论文阅读
  16. 微信服务器保留几年记录_企业微信朋友圈管理的工具
  17. Quartus-II的安装教程
  18. 卧槽,又来一个Python神器!!
  19. 【I²C总线通信协议总结】
  20. 坚果保龄球题解(c++)

热门文章

  1. 桌面上多了个恶意IE图标的删除方法
  2. 【20211214】【信号处理】从Matlab仿真的角度理解频谱混叠和奈奎斯特采样定理
  3. node-little-db小型本地json文件数据库
  4. 平价又好用的蓝牙耳机推荐,有哪些平价好用的蓝牙耳机
  5. 交互媒体专题设计之一艺工交叉
  6. 百思不得姐网站 Scrapy爬虫笔记
  7. Python中的split(‘/‘)[-2]到底怎么用?【仅供自己后续查看】
  8. python常用三种占位符
  9. python iloc函数_python:利用iloc语句对列表的分类变量进行操作
  10. 9月热钱流入环比加速 多为投机性资金