B02、分析GC日志-6.3

1、相关GC日志参数

  1. -verbose:gc 输出gc日志信息,默认输出到标准输出
  2. -XX:+PrintGC 输出GC日志。类似:-verbose:gc
  3. -XX:+PrintGCDetails 在发生垃圾回收时打印内存回收详细的日志,
    并在进程退出时输出当前内存各区域分配情况
  4. -XX:+PrintGCTimeStamps 输出GC发生时的时间戳
  5. -XX:+PrintGCDateStamps 输出GC发生时的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
  6. -XX:+PrintHeapAtGC 每一次GC前和GC后,都打印堆信息
  7. -Xloggc:<file> 表示把GC日志写入到一个文件中去,而不是打印到标准输出中

2、GC日志格式

2.1、GC 日志分类

2.1.1、Minor GC

        Minor GC又叫oung GC或YGC,完整的输出日志:

[GC (Allocation Failure) [PSYoungGen: 31744K->2192K(36864K)] 31744K->2200K(121856K), 0.0139308 secs] [Times: user=0.05 sys=0.01, real=0.01 secs] 

        根据上图解析示意图可得知以下规律:

2.1.2、Full GC

[GC (Allocation Failure) [PSYoungGen: 31744K->2192K(36864K)] 31744K->2200K(121856K), 0.0139308 secs] [Times: user=0.05 sys=0.01, real=0.01 secs]

2.1.3、补充说明

  1. "[GC" 和 "[Full GC" 说明了这次垃圾收集的停顿类型,如果有 "Full" 则说明 GC 发生了 "Stop The World"
  2. 使用 Serial 收集器在 新生代的名字是 Default New Generation,因此显示的是 "[DefNew"
  3. 使用 ParNew 收集器在新生代的名字会变成 "[ParNew",意思是 "Parallel New Generation"
  4. 使用 Parallel scavenge 收集器在新生代的名字是  "[PSYoungGen"
  5. 使用Parallel Old Generation收集器在老年代的名字是 "[ParOldGen"
  6. 使用G1收集器的话,会显示为 "garbage-first heap"

Allocation Failure:表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。

2.2、GC日志结构

2.2.1、GC 前后情况

        通过图示,我们可以发现GC日志格式的规律一般都是:GC前内存占用—>GC后内存占用(该区域内存总大小):

[PSYoungGen: 5986K->696K(8704K)] 5986K->704K(9216K)

  • 括号内:GC回收前年轻代堆大小,回收后大小,(年轻代堆总大小)
  • 括号外:GC回收前年轻代和老年代大小,回收后大小,(年轻代和老年代总大小)

2.2.3、GC 时间

        GC日志中有三个时间:user,sys和real

  1. user – 进程执行用户态代码(核心之外)所使用的时间。这是执行此进程所使用的实际 CPU 时间,其他进程和此进程阻塞的时间并不包括在内。在垃圾收集的情况下,表示 GC 线程执行所使用的 CPU 总时间。
  2. sys – 进程在内核态消耗的 CPU 时间,即在内核执行系统调用或等待系统事件所使用的 CPU 时间
  3. real – 程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间(比如等待 I/O 完成)。对于并行gc,这个数字应该接近(用户时间+系统时间)除以垃圾收集器使用的线程数。

        由于多核的原因,一般的GC事件中,real time是小于sys + user time的,因为一般是多个线程并发的去做GC,所以real time是要小于sys+user time的。如果real>sys+user的话,则你的应用可能存在下列问题:IO负载非常重或者是CPU不够用

2.3、Minor GC 日志解析

2023-11-20T17:19:43.265-0800: 0.822: [GC (ALLOCATION FAILURE) [PSYOUNGGEN: 76800K->8433K(89600K)] 76800K->8449K(294400K), 0.0088371 SECS] [TIMES: USER=0.02 SYS=0.01, REAL=0.01 SECS] 

  • (2023-11-20T17:19:43.265-0800):日志打印时间 日期格式  如 2024-05-04T21:53:59.234+0800
  • (0.822:):gc发生时,Java虚拟机启动以来经过的秒数
  • ([GC (Allocation Failure)):发生了一次垃圾回收,这是一次 Minor GC 。它不区分新生代 GC 还是老年代 GC,括号里的内容是gc发生的原因,这里的 Allocation Failure 的原因是新生代中没有足够区域能够存放需要分配的数据而失败。
  • ([PSYoungGen: 76800K->8433K(89600K)]):
    • PSYoungGen:表示GC发生的区域,区域名称与使用的GC 收集器是密切相关的
      • Serial收集器:Default New Generation  显示DefNew
      • ParNew收集器:ParNew
      • Parallel Scanvenge收集器: PSYoung
      • 老年代和新生代同理,也是和收集器名称相关
    • 76800K->8433K(89600K):GC 前该内存区域已使用容量 - > GC 后该区域容量 (该区域总容量)
      • 如果是新生代,总容量则会显示整个新生代内存的9/10,即 eden+from/to 区
      • 如果是老年代,总容量则是全部内存大小,无变化
  • (76800K->8449K(294400K)):在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:GC 前堆内存已使用容量 - > GC 堆内存容量(堆内存总容量),堆内存总容量 = 9/10 新生代+ 老年代 < 初始化的内存大小
  • (, 0.0088371 secs]):整个GC所花费的时间,单位是秒
  • ([Times: user=0.02 sys=0.01, real=0.01 secs]):
    • user:指的是CPU工作在用户态所花费的时间
    • sys:指的是CPU工作在内核态所花费的时间
    • real:指的是在此次GC事件中所花费的总时间

2.4、Full GC 日志解析

2023-11-20T17:19:43.794-0800: 1.351: [FULL GC (METADATA GC THRESHOLD) [PSYOUNGGEN: 10082K->0K(89600K)] [PAROLDGEN: 32K->9638K(204800K)] 10114K->9638K(294400K),
 [METASPACE: 20158K->20156K(1067008K)], 0.0285388 SECS] [TIMES: USER=0.11 SYS=0.00, REAL=0.03 SECS] 

  • (2023-11-20T17:19:43.794-0800):日志打印时间 日期格式  如 2013-05-04T21:53:59.234+0800
  • (1.351):gc发生时,Java虚拟机启动以来经过的秒数
  • (Full GC (Metadata GC Threshold)):
    • 发生了一次垃圾回收,这是一次FULL GC 。它不区分新生代 GC 还是老年代 GC
    • 括号里的内容是gc发生的原因,这里的 Metadata GC Threshold 的原因是 Metaspace 区不够用了
      • Full GC (Ergonomics) :JVM 自适应调整导致的GC
      • Full GC (System): 调用了System.gc( ) 方法
  • ([PSYoungGen: 10082K->0K(89600K)]):
    • PSYoungGen:表示GC发生的区域,区域名称与使用的GC 收集器是密切相关的
      • Serial收集器:Default New Generation  显示DefNew
      • ParNew收集器:ParNew
      • Parallel Scanvenge收集器: PSYoung
      • 老年代和新生代同理,也是和收集器名称相关
    • 10082K->0K(89600K):GC 前该内存区域已使用容量 - > GC 后该区域容量 (该区域总容量)
      • 如果是新生代,总容量则会显示整个新生代内存的9/10,即 eden+from/to 区
      • 如果是老年代,总容量则是全部内存大小,无变化
  • ([ParOldGen: 32K->9638K(204800K)]):老年代区域没有发生GC,因为本次GC是metaspace 引起的
  • (10114K->9638K(294400K),):在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:GC 前堆内存已使用容量 - > GC 堆内存容量(堆内存总容量)堆内存总容量 = 9/10 新生代+ 老年代 < 初始化的内存大小
  • ([Metaspace: 20158K->20156K(1067008K)],):metaspace GC  回收2K空间
  • (0.0285388 secs):整个GC所花费的时间,单位是秒
  • ([Times: user=0.11 sys=0.00, real=0.03 secs]):
    • user:指的是CPU工作在用户态所花费的时间
    • sys:指的是CPU工作在内核态所花费的时间
    • real:指的是在此次GC事件中所花费的总时间

3、案例演示

3.1、代码示例

package blnp.net.cn.jvm.demos;

/**
 *
 * 在jdk7 和 jdk8中分别执行
 *  -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC
 *
 * @author lyb 2045165565@qq.com
 * @createDate 2024/4/7 14:49
 */
public class GcLogTest {

    private static final int _1MB = 1024 * 1024;

    public static void testAllocation() {
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation4 = new byte[4 * _1MB];
    }

    public static void main(String[] agrs) {
        testAllocation();
    }

}

JDK1.7.0_080版本的执行结果:

Connected to the target VM, address: '127.0.0.1:56576', transport: 'socket'
[GC[DefNew: 8174K->618K(9216K), 0.0050449 secs] 8174K->6762K(19456K), 0.0051236 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 def new generation   total 9216K, used 4879K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
  eden space 8192K,  52% used [0x00000000f9a00000, 0x00000000f9e296c0, 0x00000000fa200000)
  from space 1024K,  60% used [0x00000000fa300000, 0x00000000fa39a900, 0x00000000fa400000)
  to   space 1024K,   0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
 tenured generation   total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
   the space 10240K,  60% used [0x00000000fa400000, 0x00000000faa00030, 0x00000000faa00200, 0x00000000fae00000)
 compacting perm gen  total 21248K, used 3049K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
   the space 21248K,  14% used [0x00000000fae00000, 0x00000000fb0fa698, 0x00000000fb0fa800, 0x00000000fc2c0000)
No shared spaces configured.
Disconnected from the target VM, address: '127.0.0.1:56576', transport: 'socket'

JDK1.8.0_321版本的执行结果:

Connected to the target VM, address: '127.0.0.1:49940', transport: 'socket'
[GC (Allocation Failure) [DefNew: 6517K->676K(9216K), 0.0024239 secs] 6517K->4772K(19456K), 0.0024547 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 7224K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  eden space 8192K,  79% used [0x00000000fec00000, 0x00000000ff264f08, 0x00000000ff400000)
  from space 1024K,  66% used [0x00000000ff500000, 0x00000000ff5a9320, 0x00000000ff600000)
  to   space 1024K,   0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
 tenured generation   total 10240K, used 4096K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
   the space 10240K,  40% used [0x00000000ff600000, 0x00000000ffa00020, 0x00000000ffa00200, 0x0000000100000000)
 Metaspace       used 3100K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 327K, capacity 392K, committed 512K, reserved 1048576K
Disconnected from the target VM, address: '127.0.0.1:49940', transport: 'socket'

3.2、图解过程

JDK1.7

JDK1.8

4、GC日志分析工具

4.1、GCeasy

        官网地址,GCeasy是一款在线的GC日志分析器,可以通过GC日志分析进行内存泄漏检测、GC暂停原因分析、JVM配置建议优化等功能,而且是可以免费使用的(有一些服务是收费的)。

注意:该站点国内访问较不稳定,如果打开失败可以多刷新几次。

4.2、GCView

        GCViewer是一个免费的、开源的分析小工具,用于可视化查看由SUN/Oracle,IBM,HP和BEA Java虚拟机产生的垃圾收集器的日志。

        GCViewer用于可视化Java VM选项-verbose:gc 和.NET生成的数据-Xloggc:<file>。它还计算与垃圾回收相关的性能指标(吞吐量,累积的暂停,最长的暂停等)。当通过更改世代大小或设置初始堆大小来调整特定应用程序的垃圾回收时,此功能非常有用。

        下载地址,只需双击gcviewer-1.3x.jar或运行java -jar gcviewer-1.3x.jar(它需要运行java 1.8 vm),即可启动GCViewer(gui)。

4.3、其它工具

4.3.1、HPjmeter

        工具很强大,但只能打开由以下参数生成的GC log, -verbose:gc -Xloggc:gc.log。添加其他参数生成的gc.log无法打开。HPjmeter集成了以前的HPjtune功能,可以分析在HP机器上产生的垃圾回收日志文件。

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

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

相关文章

【第二十七篇】几款配合Burpsuite使用的Google插件(Wappalyzer、FindSomething、FOFAproView等)

文章目录 WappalyzerFindSomethingFOFA Pro ViewsuperSearchPluswayback machinesource detecotorX-Forwarded-For Header以下插件均在Google应用商店中下载 Wappalyzer Wappalyzer是一个用于识别网站所使用的技术和工具的浏览器扩展程序。它能够检测出网站所使用的内容管理系…

2024年生成式人工智能的现状:进展、挑战与未来展望的深入分析

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

主流三种驱动器方案特点简介

三种执行器原理相似&#xff0c;但在结构和部件上略有区别&#xff0c;因此在精度、响应速度等指标上 呈现不同效果&#xff1a; &#xff08;1&#xff09;TSA&#xff08;刚性驱动器&#xff09;&#xff1a;常规高速电机高传动比减速机高刚度力矩传感器&#xff0c;减 速机…

Java入门基础知识第九课——二维数组

前面二白讲了关于一维数组的相关知识和操作&#xff0c;Java中的二维数组本质上是每个一维数组都包含一个或多个元素&#xff0c;其中每个元素都代表二维数组中的一个元素。二维数组一般应用在矩阵的一些运算、二维数据的处理、图表的绘制、数据库的存储等方面。特别是在处理数…

运筹学基础(六)列生成算法(Column generation)

文章目录 前言从Cutting stock problem说起常规建模Column generation reformulation 列生成法核心思想相关概念Master Problem (MP)Linear Master Problem (LMP)Restricted Linear Master Problem (RLMP)subproblem&#xff08;核能预警&#xff0c;非常重要&#xff09; 算法…

【学习】软件测试中,我们为什么要进行系统测试

软件测试中的系统测试是一个关键环节&#xff0c;它主要是通过测试整个系统来验证软件是否满足需求规格说明书中的要求。在软件开发周期的后期&#xff0c;系统测试扮演着非常重要的角色&#xff0c;因为它可以发现并纠正软件中存在的错误和缺陷&#xff0c;确保软件的质量和稳…

Google视觉机器人超级汇总:从RT、RT-2到AutoRT/SARA-RT/RT-Trajectory、RT-H

前言 随着对视觉语言机器人研究的深入&#xff0c;发现Google的工作很值得深挖&#xff0c;比如RT-2 ​想到很多工作都是站在Google的肩上做产品和应用&#xff0c;​Google真是科技进步的核心推动力&#xff0c;做了大量大模型的基础设施&#xff0c;服(推荐重点关注下Googl…

P1731 [NOI1999] 生日蛋糕——典型的回溯和剪枝题目,值得一看

今天尝试了一下md的编辑器&#xff0c;不知道有没有什么改变 [NOI1999] 生日蛋糕 题目背景 数据加强版 link 题目描述 7 月 17 日是 Mr.W 的生日&#xff0c;ACM-THU 为此要制作一个体积为 N π N\pi Nπ 的 M M M 层生日蛋糕&#xff0c;每层都是一个圆柱体。 设从下往…

scrapy 爬取m3u8视频

scrapy 爬取m3u8视频 【一】效果展示 爬取ts文件样式 合成的MP4文件 【二】分析m3u8文件路径 视频地址&#xff1a;[在线播放我独自升级 第03集 - 高清资源](https://www.physkan.com/ph/175552-8-3.html) 【1】找到m3u8文件 这里任务目标很明确 就是找m3u8文件 打开浏览器…

鸿蒙OS开发实战:【自动化测试框架】使用指南

概述 为支撑HarmonyOS操作系统的自动化测试活动开展&#xff0c;我们提供了支持JS/TS语言的单元及UI测试框架&#xff0c;支持开发者针对应用接口进行单元测试&#xff0c;并且可基于UI操作进行UI自动化脚本的编写。 本指南重点介绍自动化测试框架的主要功能&#xff0c;同时…

基于Java+SpringBoot+Vue文学名著分享系统(源码+文档+部署+讲解)

一.系统概述 随着世界经济信息化、全球化的到来和互联网的飞速发展&#xff0c;推动了各行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、动态的、交互友好的、高效的文学名著分享系统。当前的信息管理…

深入探索实时音视频技术:RTC程序设计权威指南

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

BUUCTF刷题十一道(12)SSTI专题一

文章目录 学习文章[Flask]SSTI[GWCTF 2019]你的名字[第三章 web进阶]SSTI[pasecactf_2019]flask_ssti[NewStarCTF 公开赛赛道]BabySSTI_One[Dest0g3 520迎新赛]EasySSTI[NewStarCTF 公开赛赛道]BabySSTI_Two[NewStarCTF 公开赛赛道]BabySSTI_Three[GYCTF2020]FlaskApp[CSCCTF 2…

java基础语法(13)

1. final关键字 final概述 学习了继承后&#xff0c;我们知道&#xff0c;子类可以在父类的基础上改写父类内容&#xff0c;比如&#xff0c;方法重写。那么我们能不能随意的继承API中提供的类&#xff0c;改写其内容呢&#xff1f;显然这是不合适的。为了避免这种随意改写的情…

关于转义符 \ 在php正则中的匹配问题

今天做题遇到一个很经典的问题&#xff0c;记录一下&#xff0c;先看一段代码 <?php $str&#xff0c;&#xff0c;"\\"; $pattern&#xff0c;&#xff0c;"/\\/"; if(preg_match($partern,$str,$arr)) { &#xff0c;&#xff0c;&#xff0c;&…

结构型模式--1.适配器模式【托尼托尼·乔巴】

1. 翻译家 在海贼王中&#xff0c;托尼托尼乔巴&#xff08;Tony Tony Chopper&#xff09;是草帽海贼团的船医&#xff0c;它本来是一头驯鹿&#xff0c;但是误食了动物系人人果实之后可以变成人的形态。 乔巴吃了恶魔果实之后的战斗力暂且抛开不谈&#xff0c;说说它掌握的第…

金仓数据库Kingbase的数据库开发管理工具KStudio连接乱码

背景&#xff1a; 金仓数据库V8R6&#xff0c;KStudio在Windows10上运行&#xff0c;JDK8 问题&#xff1a; 使用客户端连接数据库时&#xff0c;提示信息乱码&#xff0c;首选项设置字符集不管用&#xff0c;具体如下图所示&#xff1a; Before&#xff1a; After&#xff1…

018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 协议 二、 驱动代码 三、 应用代码 四、 实验 五、 程序优化 一、 模块介绍 1.1 简介 红外遥控被广泛应用于家用电器、工业控制和智能仪器系统中&#xff0c;像我们熟知的有电视机盒子遥控器、空调遥控器。红外遥控器系统分为发送端和…

【On Hold】又一本ESCI被紧急On Hold!!年发文量激增19倍令人匪夷所思

【SciencePub学术】前几日Hindawi撤稿事件闹得沸沸扬扬&#xff0c;整个学术界的关注点都在这次的撤稿事件。所有的期刊都进入自检模式&#xff0c;官方在审核期刊资质时也颇为严格了。 但是经小编查阅资料时发现&#xff0c;最近有一本ESCI期刊又被科睿唯安官方打上了On Hold…

基于SpringBoot+Vue的“漫画之家”系统(源码+文档+部署+讲解)

一.系统概述 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理…
最新文章