JVM实战(16)——模拟Young GC

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

本章,我们将通过示例代码演示Young GC是如何发生的。同时,我们会讲解如何通过JVM参数去配置打印GC日日,然后通过GC日志分析JVM中的GC到底是如何运行的。

1.1 JVM内存参数

我们的示例程序基于JDK1.8,JVM参数如下:
-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC

上述参数中:

  • -XX:NewSize=5242880 -XX:MaxNewSize=5242880:新生代大小5MB
  • -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760:Java堆内存10MB
  • -XX:SurvivorRatio=8:Eden区占4MB,Survivor各占0.5MB
  • -XX:PretenureSizeThreshold=10485760:大对象阈值10MB
  • -XX:+UseParNewGC -XX:+UseConcMarkSweepGC:新生代使用ParNew,老年代使用CMS

1.2 GC日志参数

我们需要在系统的JVM参数中加入GC日志的打印选型:

  • -XX:+PrintGCDetails:打印详细的GC日志
  • -XX:+PrintGCTimeStamps:打印每次GC发生的时间
  • -Xloggc:gc.log:设置将GC日志写入一个磁盘文件

加入日志参数后,JVM的参数如下:

-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log

二、示例程序

2.1 程序源码

示例程序代码如下:

    public class Demo1 {
        public static void main(String[] args) {
            byte[] array1 = new byte[1024 * 1024];
            array1 = new byte[1024 * 1024];
            array1 = new byte[1024 * 1024];
            array1 = null;
    
            byte[] array2 = new byte[2 * 1024 * 1024];
        }
    }

2.2 JVM内存模型

我们根据上述代码来分析下对象是如何在Eden区分配的。

首先,main方法里的第一行代码会为Eden区创建一个1MB的byte数组,第2-3行代码array1局部变量重新赋值引用:

第4行代码array1=null,这时之前的3个数组对象都失去了引用:

第5行代码byte[] array2 = new byte[2 * 1024 * 1024],尝试创建一个2MB的对象放入Eden区,但是Eden区已经空间不足了,所以这时就会触发新生代的Young GC。

2.3 程序执行

当使用IDE执行程序时,我们先要进行JVM参数配置,以IDEA为例,配置如下:

运行完成后,工程目录下会出现GC日志文件:gc.log,内容如下:

    Java HotSpot(TM) 64-Bit Server VM (25.111-b14) for windows-amd64 JRE (1.8.0_111-b14), built on Sep 22 2016 19:24:05 by "java_re" with MS VC++ 10.0 (VS2010)
    Memory: 4k page, physical 12470176k(6211924k free), swap 14370720k(6127712k free)
    CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=5242880 -XX:NewSize=5242880 -XX:OldPLABSize=16 -XX:PretenureSizeThreshold=10485760 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC 
    0.242: [GC (Allocation Failure) 0.242: [ParNew: 4094K->512K(4608K), 0.0018168 secs] 4094K->1696K(9728K), 0.0020491 secs] [Times: user=0.05 sys=0.02, real=0.00 secs] 
    Heap
     par new generation   total 4608K, used 3702K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
      eden space 4096K,  77% used [0x00000000ff600000, 0x00000000ff91d978, 0x00000000ffa00000)
      from space 512K, 100% used [0x00000000ffa80000, 0x00000000ffb00000, 0x00000000ffb00000)
      to   space 512K,   0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
     concurrent mark-sweep generation total 5120K, used 1184K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
     Metaspace       used 3484K, capacity 4498K, committed 4864K, reserved 1056768K
      class space    used 387K, capacity 390K, committed 512K, reserved 1048576K

三、日志分析

本节,我们来分析下上述的gc.log日志。

3.1 GC情况概览

我们先来看下日志中的如下行,这是本次GC情况的概要说明:

    0.242: [GC (Allocation Failure) 0.242: [ParNew: 4094K->512K(4608K), 0.0018168 secs] 4094K->1696K(9728K), 0.0020491 secs] [Times: user=0.05 sys=0.02, real=0.00 secs]

GC (Allocation Failure) : 说明了为啥发生GC,因为对象分配失败,也就是上述的Eden区空间不足了;

0.242: 系统运行了0.242秒以后,发生了本次GC;

ParNew: 4094K->512K(4608K), 0.0018168 secs: 使用ParNew进行新生代的GC,GC前新生代使用了4094K,GC完成后新生代使用了512K,4608K表示年轻代的总空间(Eden+1个Survivor),本次GC耗时0.0018168秒;

4094K->1696K(9728K), 0.0020491 secs: Java堆内存的总空间为8728K,GC前使用了4094K,GC后使用了1696K;

Times: user=0.05 sys=0.02, real=0.00 secs: 本次GC消耗的时间,与元数据区有关,后续讲解。

根据GC日志可以看出,本轮Young GC有512K对象存活下来了,从Eden区转移到了Survivor区:

3.2 JVM退出时堆内存

我们接着看下面的GC日志,这是 JVM退出时当前Java堆内存的使用情况 :

    Heap
     par new generation   total 4608K, used 3702K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
      eden space 4096K,  77% used [0x00000000ff600000, 0x00000000ff91d978, 0x00000000ffa00000)
      from space 512K, 100% used [0x00000000ffa80000, 0x00000000ffb00000, 0x00000000ffb00000)
      to   space 512K,   0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)

par new generation total 4608K, used 3702K: ParNew负责的新生代总共有4608K内存,目前使用了3702K;

eden space 4096K, 77% used: Eden总共使用了4096K

from space 512K, 100% used: From Survivor区使用了100%(存放转移过来的未知存活对象)

to space 512K, 0% used: To Survivor区未使用

我们接着看:

    concurrent mark-sweep generation total 5120K, used 1184K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
    Metaspace       used 3484K, capacity 4498K, committed 4864K, reserved 1056768K
    class space    used 387K, capacity 390K, committed 512K, reserved 1048576K

concurrent mark-sweep generation total 5120K, used 1184K: 使用CMS管理的老年代总空间为5210K,已使用1184K

Metaspace used 3484K, capacity 4498K, committed 4864K, reserved 1056768K: 元数据区的空间信息

class space used 387K, capacity 390K, committed 512K, reserved 1048576K: Class空间信息

JDK1.8开始,取消了方法区,取而代之的是Metaspace。Metaspace直接使用本地内存。默认情况下,其大小会根据使用情况动态调整,也可以使用-XX:MaxMetaspaceSize来控制最大内存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/321844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python轴承故障诊断 (11)基于VMD+CNN-BiGRU-Attenion的故障分类

目录 往期精彩内容: 前言 模型整体结构 1 变分模态分解VMD的Python示例 2 轴承故障数据的预处理 2.1 导入数据 2.2 故障VMD分解可视化 2.3 故障数据的VMD分解预处理 3 基于VMD-CNN-BiGRU-Attenion的轴承故障诊断分类 3.1 定义VMD-CNN-BiGRU-Attenion分类网…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -关于我们页面实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

6.Linux环境变量

Linux环境变量能帮你提升Linux shell体验。很多程序和脚本都通过环境变量来获取系统信息、存储临时数据和配置信息。在Linux系统上有很多地方可以设置环境变量,了解去哪里设置相应的环境变量很重要。 总结 命令作用示例注释env查看全局环境变量envprintenv查看全局…

【Scala】——面向对象

1 Scala 包 1.1 包风格 Scala 有两种包的管理风格。 第一种 Java 的包管理风格相同,每个源文件一个包(包 名和源文件所在路径不要求必须一致),包名用“.”进行分隔以表示包的层级关系,如 com.atguigu.scala。另一种风…

【极光系列】springBoot集成xxl-job调度器

【springboot集成xxl-job】 一.gitee地址 直接下载可用 https://gitee.com/shawsongyue/aurora.git 模块:aurora_xxl_job 二.mysql安装教程 参考我的另一篇文章:https://blog.csdn.net/weixin_40736233/article/details/135582926?spm1001.2014.30…

手写netty通信框架以及常见问题

目录 通信框架设计 实现功能点 通信模型 消息定义 可靠性设计 代码 服务端代码 常见netty问题 如何让netty支持百万长连接? 1. 操作系统层面优化 2. netty层面优化 2.1 设置合理线程 2.2 心跳优化 2.3 合理使用内存池 2.4 IO线程与业务线程剥离 3. JVM层面优化 …

WinSCP传文件到Ubuntu提示Permission denied

使用WinSCP传文件到一台Ubuntu服务器时,提示Permission denied。 客户端:Windows 10 服务器:hyper-V虚拟机 Ubuntu 20.04 WinSCP版本:WinSCP 6.1 文章目录 WinSCP工具介绍WinSCP开源免费WinSCP优点 Permission denied 解决方法scp…

QA Office and Security Room

QA办公室和安全室是一个完全模块化的套件,有450多个对象,可以让你用任意数量的楼层构建自己的办公楼内部。 支持内置URP。 这个包的演示场景包含许多不同的房间,如接待大厅、办公室、主任室和秘书室、会议厅、卫生间、储藏室、保安室、地下停车场的出口。此外,这个包还包括…

Prepar3D多屏合成失败全屏显示失败

P3D需要设置全屏显示,详细设置参考P3D全屏设置中的方法。 一、排查硬件问题 包括屏幕数据链接线等。 二、没有启用Surround (1)查看是否启用了Surround方法 打开 NVIDIA 控制面板,通常可以在桌面上右键单击并选择相应的选项。在显卡控制…

MySQL——性能优化与关系型数据库

文章目录 什么是性能?什么是关系型数据库?数据库设计范式 常见的数据库SQL语言结构化查询语言的六个部分版本 MySQL数据库故事历史版本5.6/5.7差异5.7/8.0差异 什么是性能? 吞吐与延迟:有些结论是反直觉的,指导我们关…

Hive基础知识(十五):Hive中SQL排序方式全解

1. 全局排序(Order By) Order By:全局排序,只有一个 Reducer 1)使用 ORDER BY 子句排序 ASC(ascend): 升序(默认) DESC(descend): 降序 2&#…

【题解】—— 每日一道题目栏

2024.1 【题解】—— LeetCode一周小结1 1. 1599. 经营摩天轮的最大利润 2. 466. 统计重复个数 3. 2487. 从链表中移除节点 4. 2397. 被列覆盖的最多行数 5. 1944. 队列中可以看到的人数 6. 2807. 在链表中插入最大公约数 7. 383. 赎金信 【题解】—— LeetCode一周小…

爬虫入门学习(二)——response对象

大家好!我是码银,代码的码,银子的银🥰 欢迎关注🥰: CSDN:码银 公众号:码银学编程 前言 在本篇文章,我们继续讨论request模块。从上一节(爬虫学习(1)--reque…

CTF伪随机数爆破

要了解伪随机数的爆破首先你的先知道什么是PHP种子, 借用在rand()函数中,我们可以通过设置随机数种子来影响随机数的生成。例如,在rand()函数中加入了随机数种子编码后,每次运行程序将会生成同样的随机整数序列。这个就是伪随机数…

Vue报错 Cannot find module ‘../../modules/es6.symbol‘解决办法

在进行webpack打包的时候,会出现Cannot find module XXX’的错误,找不到某个模块的错误,今天给出解决方法: 直接进行npm install重新打包;如果npm install重新打包之后,仍然出现这个问题,可以进…

网站建设网络设计营销类网站eyouCMS模板(PC+WAP)

模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统,原创设计、手工书写DIVCSS,完美兼容IE7、Firefox、Chrome、360浏览器等;主流浏览器;结构容易优化;多终端均可正常预览。

我为什么要写RocketMQ消息中间件实战派上下册这本书?

我与RocketMQ结识于2018年,那个时候RocketMQ还不是Apache的顶级项目,并且我还在自己的公司做过RocketMQ的技术分享,并且它的布道和推广,还是在之前的首席架构师的带领下去做的,并且之前有一个技术神经质的人&#xff0…

Softmax回归(多类分类模型)

目录 1.对真实值类别编码:2.预测值:3.目标函数要求:4.使用Softmax模型将输出置信度Oi计算转换为输出匹配概率y^i:5.使用交叉熵作为损失函数:6.代码实现: 1.对真实值类别编码: y为真实值&#xf…

实战指南:如何在Spring Boot中无缝整合Dubbo【四】

欢迎来到我的博客,代码的世界里,每一行都是一个故事 实战指南:如何在Spring Boot中无缝整合Dubbo【四】 前言项目结构主项目(作为主pom)接口服务提供者properties文件实现类 服务消费者properties接口层 实现效果图 前言 微服务架构已经成为…

前端开发必备:掌握正则表达式,轻松应对复杂的表单验证

前言 在前端开发中,经常需要处理 URL 地址、校验手机号合法性、提取域名等。正则表达式是一种常用的工具。通过使用正则表达式,我们可以对用户输入进行有效的验证,确保数据的合法性和完整性。本文将介绍一些常见的正则表达式,帮助…