面试题集中营—GC日志简析及频繁GC的调优

如何查看GC日志

        有两种方式查看GC日志,一种是动态命令行查看

        jstat  -gc <pid> 300 5

        第二种就是在JVM参数中增加打印的参数,如下:

       -XX:+PrintGCDetails -XX:+PrintGCTimeStamps   表示打印每次GC的日志以及GC发生的时间

        -Xloggc:gc.log 可以把gc日志写入文件中

JVM配置的堆结构

        -XX:NewSize=5M -XX:MaxNewSize=5M -XX:InitialHeapSize=10M -XX:MaxHeapSize=10M

 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

        新生代:5M、老年代:5M、Eden区:4M、FromSurvivor和ToSurvivor都是0.5M

GC日志说明

我们来看一个GC日志的打印结果:

0.144: [GC (Allocation Failure) 0.144: [ParNew: 3699K->510K(4608K), 0.0030788 secs] 3699K->1641K(9728K), 0.0031282 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 par new generation   total 4608K, used 3745K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
  eden space 4096K,  78% used [0x00000000ff600000, 0x00000000ff928980, 0x00000000ffa00000)
  from space 512K,  99% used [0x00000000ffa80000, 0x00000000ffaffb40, 0x00000000ffb00000)
  to   space 512K,   0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
 concurrent mark-sweep generation total 5120K, used 1130K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 3151K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 344K, capacity 388K, committed 512K, reserved 1048576K

        第一行是运行时的打印,后面是程序退出时的堆内存结果打印。

        第一行的0.144表示程序运行开始后0.144秒发生了一个GC。这是一次年轻代的GC,年轻代的GC算法是ParNew,3699K->510K表示本次GC清理的空间,4608K表示年轻代的总的可用空间,最后的时间0.0030788s 表示本次GC的时间。后面紧跟着的是年轻代GC前后堆的占用情况,后面9728K是堆内存的总大小。user、sys、real表示用户耗时,系统耗时和实际耗时。

       JVM退出时打印的结果分析:分成了三个部分

       1、年轻代管理,从这里我们能够看出年轻代、Eden区和Survivor区的空间及使用比例。

       2、老年代管理,老年代的GC算法和空间使用情况。

       3、元数据区, 元数据区域及class空间的使用情况。

     JDK1.8默认垃圾处理器

       我们把 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC去掉,来查看一下默认情况下的GC日志。

0.177: [GC (Allocation Failure) [PSYoungGen: 3706K->488K(4608K)] 3706K->1700K(9728K), 0.0068803 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 4608K, used 3711K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
  eden space 4096K, 78% used [0x00000000ffb00000,0x00000000ffe25c30,0x00000000fff00000)
  from space 512K, 95% used [0x00000000fff00000,0x00000000fff7a020,0x00000000fff80000)
  to   space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
 ParOldGen       total 5120K, used 1212K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
  object space 5120K, 23% used [0x00000000ff600000,0x00000000ff72f020,0x00000000ffb00000)
 Metaspace       used 3154K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 345K, capacity 388K, committed 512K, reserved 1048576K

        上述我们可以看到JDK1.8默认的年轻代垃圾处理器是PSYoungGen,默认的老年代垃圾回收器是ParOldGen。我们后面会单开一章来详细说明一下有关垃圾收集器的概念。

频繁GC调优

       GC分成Minor GC、Major GC 和 Full GC

       Minor GC:从年轻代空间回收内容,也成为Young GC

       Major GC:从老年代空间回收内存

       Full GC:清理整个内容堆 - 既包括年轻代也包括老年代

     Minor GC与Major GC过多

       Minor GC:就是年轻代空间太少不足以分配新的对象,就需要GC。Minor GC过多自然会导致Major GC变多,因为对于无法释放的对象,在多次复制移动后根据复制次数就会转移到老年代。        

      注: Major GC只有CMS这个垃圾回收器才有。

       解决方法:

       1、优化代码逻辑:这里可以参考

       2、如果应用存在大量的短期对象,就适当的增加年轻代的大小;如果应用存在较多的持久对象就适当的增加老年代的大小;

     Full GC

        Full GC(Full Garbage Collection)是对整个堆内存(包括年轻代、老年代、永久代或Metaspace等)进行清理的一种垃圾回收操作。触发Full GC的条件可能包括老年代空间不足、永久代/Metaspace空间不足、显式调用System.gc()等。Full GC的执行会导致相对较长的停顿时间,因为它需要对整个堆内存进行回收。

        CMS垃圾收集器的Full GC日志如下:

38.342: [GC (Allocation Failure) 38.342: [ParNew: 6144K->640K(6144K), 0.0027651 secs] 11491K->8130K(19840K), 0.0028367 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
38.345: [GC (CMS Initial Mark) [1 CMS-initial-mark: 7490K(13696K)] 8146K(19840K), 0.0004821 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
38.345: [CMS-concurrent-mark-start]
38.351: [CMS-concurrent-mark: 0.006/0.006 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
38.351: [CMS-concurrent-preclean-start]
38.351: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
38.351: [GC (CMS Final Remark) [YG occupancy: 1073 K (6144 K)]38.351: [Rescan (parallel) , 0.0002674 secs]38.352: [weak refs processing, 0.0000457 secs]38.352: [class unloading, 0.0006265 secs]38.352: [scrub symbol table, 0.0004225 secs]38.353: [scrub string table, 0.0001100 secs][1 CMS-remark: 7490K(13696K)] 8564K(19840K), 0.0015694 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
38.353: [CMS-concurrent-sweep-start]
38.355: [CMS-concurrent-sweep: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
38.355: [CMS-concurrent-reset-start]
38.355: [CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

        解析:FullGC也会包括一次年轻代的GC,我们主要还是从第二行开始看

        第一个阶段(CMS Initial Mark):initial-mark-初始标记节点,后面跟着的7490K是老年代的使用情况,13696K表示整个老年代的大小。8146K表示的是堆内存的使用情况,19840K是整个堆的大小。后面跟着的时间就是初始标记阶段的使用时间。这个阶段主要标记GC ROOTS,这个阶段为STW。

        第二个阶段(CMS-concurrent-mark):并发标记阶段,这个阶段是从第一阶段标记的ROOTS来找存活的对象。和应用程序是并发执行的,并不会停止应用程序。

        第三个阶段(CMS-concurrent-preclean):由于上一个阶段是并发的,那么一些对象的引用会发生变化,如果发生了变化,JVM会标记这个区域为DirtyCard。这个阶段就是重新标记。

        第四个阶段(CMS Final Remark):最终标记阶段,这个阶段会老年代全部的存活对象,包括在并发标记阶段更改或者新创建的引用对象。后面跟着的一些统计数据,比如堆内存的使用情况,扫描花费的时间等。

        第五个阶段(CMS-concurrent-sweep):并发清理阶段,不需要STW,主要是移除不需要的对象释放内存空间。

        第六个阶段(CMS-concurrent-reset):并发重置阶段,主要是为了下一次GC做准备

        Parallel垃圾收集器的Full GC日志如下:

72.884: [GC (Allocation Failure) [PSYoungGen: 6125K->500K(6144K)] 16090K->13017K(19968K), 0.0042736 secs] [Times: user=0.11 sys=0.00, real=0.00 secs] 
72.888: [Full GC (Ergonomics) [PSYoungGen: 500K->0K(6144K)] [ParOldGen: 12517K->12671K(13824K)] 13017K->12671K(19968K), [Metaspace: 5545K->5535K(1056768K)], 0.0794034 secs] [Times: user=0.38 sys=0.00, real=0.08 secs] 
89.479: [Full GC (Ergonomics) [PSYoungGen: 5632K->1599K(6144K)] [ParOldGen: 12671K->13700K(13824K)] 18303K->15299K(19968K), [Metaspace: 5536K->5536K(1056768K)], 0.0526621 secs] [Times: user=0.16 sys=0.00, real=0.05 secs] 
101.378: [Full GC (Ergonomics) [PSYoungGen: 5632K->3391K(6144K)] [ParOldGen: 13700K->13699K(13824K)] 19332K->17090K(19968K), [Metaspace: 5536K->5536K(1056768K)], 0.0493102 secs] [Times: user=0.24 sys=0.00, real=0.05 secs] 

       解析:同样的也是年轻代和老年代同时进行了一次GC。PSYoungGen:使用了Parallel Scavenge并行垃圾收集器的新生代GC前后大小的变化;ParOldGen:使用了Parallel Old并行垃圾收集器的老年代GC前后大小的变化;Metaspace: 元数据区GC前后大小的变化,JDK1.8中引入了元数据区以替代永久代;xxx secs:指GC花费的时间

     触发GC的情况

       1、代码中调用system.gc();

       2、老年代空间不足;

       3、堆中分配了大对象;

      解决方法 

        首先通过分析Full GC的过程,新生代和老年代的占用情况,还有每个阶段的时间。定位到具体的原因,比如我们发现老年代每次Full GC回收的内存很少,或者越来越少,FullGC的频率越来越快,那么就表示在堆中出现了无法释放的对象,每次回收都被标记成存活对象。此时就要配合堆分析工具查看占用内存的对象是哪些,并定位到代码中。

        其次在代码中创建了大对象,在新生代中无法分配就会直接进入老年代,这时也需要优化代码。

        原则上基本不需要怎么进行JVM调优,JVM的本身的设计是低延时高并发大吞吐量的,对于日常的服务来说基本上都可以满足了,只需要调整堆空间的大小即可。

        JVM调优的主要调整的部分:

        1、在内存大小不变的情况下,合理的内容空间分配可以提高系统的吞吐量;

        2、根据业务需要调整垃圾回收器;

        3、重点关注的区域是堆区,里面主要存放对象实例。

JDK工具

        jinfo:查看JVM配置参数信息

        jmap:查看当前程序JVM堆使用情况

        jstat:查看JVM GC统计信息

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

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

相关文章

如何解决PPT中获取加载项是灰色的,无法链接到Power BI的问题?

问题描述&#xff1a; 最近有朋友留言询问:“在尝试之前我发布的如何在PPT中展示Power BI报告的操作步骤的时候&#xff0c;想要在PPT中展示Power BI报告&#xff1f;只需这样做&#xff01; (qq.com) 碰到在PowerPoint中【获取加载项选项】是灰色&#xff0c;无法链加载Powe…

WordPress网站上添加看板娘

续接上篇——基于LNMP部署wordpress-CSDN博客 目录 一.下载并解压 二.设置头文件 修改header.php 修改配置文件footer.php 三.将你设置的主题包上传到/usr/share/nginx/html/wp-content这个目录里 四.扩展——将看板娘修改到左侧 一.下载并解压 [rootaliyun ~]# wget htt…

技术分享 | app测试中常用的Android模拟器

Emulator Emualor 是 Android Studio 自带的模拟器&#xff0c;是官方提供的工具&#xff0c;Android 开发最常使用的就是这一款。 它功能非常齐全&#xff0c;电话本、通话等功能都可正常使用。用户可以使用键盘输入&#xff0c;鼠标点击模拟器按键输入&#xff0c;甚至还可…

安卓投屏延时数据如何测试,测试工具如何写?

背景&#xff1a; 投屏其实在android等使用场景非常非常多&#xff0c;比如现在火爆小米汽车的车机&#xff0c;上面涉及到手机和车机互联画面相关都是属于投屏范围。这种跨设备的投屏场景&#xff0c;流畅的体验是最重要的&#xff0c;这里就会要求投屏中最重要的一个性能指标…

Nerf技术原理

Neural Radiance Fields (NeRF) 是一种3D场景重建技术,用于从一组稀疏的2D图像创建高质量的3D模型。这一技术基于深度学习,通过训练一个神经网络来模拟场景的体积密度和颜色分布,实现在新的视角下渲染出高质量的3D图像。 NeRF的核心原理 NeRF的核心在于使用一个全连接的神经…

开源事件通知库libevent及网络连接管理模块bufferevent详解

目录 1、libevent介绍 1.1、什么是libevent&#xff1f; 1.2、libevent特点 1.3、网络连接管理模块bufferevent 2、bufferevent有什么用&#xff1f; 3、bufferevent的整体设计与实现细节 3.1、整体概况 3.2、evbuffer与bufferevent 3.3、defer callback 4、bufferev…

听说英伟达和诺和诺德要共建医药研发超算,超算安腾默默笑了

继黄仁勋公开发表“生命科学才是未来”的观点后&#xff0c;英伟达押注生物计算赛道又有新动作。日前&#xff0c;诺和诺德基金会宣布将出资和英伟达合作&#xff0c;在丹麦建造一台专注于生成式AI应用的超级计算机&#xff0c;以推动医疗保健、生命科学和绿色转型领域的研究与…

【JavaSE进阶】08-反射机制 09-注解

1 反射机制 a) 反射的基本概念 b) Java中的类反射 c) 安全性和反射 d) 反射的两个缺点 1.1 反射的基本概念 反射的概念是由 Smith 在 1982 年首次提出的&#xff0c;主要是指程序可以访问、检测和修改它本身状 态或行为的一种能力, 并能根据自身行为的状态和结果&#…

六、项目发布 -- 2. 数据库环境准备

之前我们是采用mock方式获取这些接口&#xff0c;也就是这些接口的数据其实是固定的&#xff0c;现在我们将从数据库中来获取这些数据并且在界面上进行展示。 1、数据库环境准备 到MYSQL官网上&#xff0c;主要下载服务端&#xff0c;社区版是免费的&#xff0c;安装好MYSQL …

结构体(C语言)

“点赞&#xff0c;留言&#xff0c;收藏&#xff0c;关注” 就是对阿林最大的支持 1.自定义类型 什么是自定义类型&#xff1f;C语言中有一些自带的数据类型&#xff0c;比如说char&#xff0c;int&#xff0c;float&#xff0c;double&#xff0c;long等数据类型就是C语言的…

目标检测——标注鱼类数据集

一、重要性及意义 鱼类的检测在多个领域都表现出其重要性和意义。以下是几个主要方面的阐述&#xff1a; 首先&#xff0c;从食品安全和营养价值的角度来看&#xff0c;鱼类作为人们日常生活中的重要蛋白质来源&#xff0c;其质量和安全性备受关注。鱼类营养成分检测能够评估…

C++异步回调示例:多线程执行任务,主线程通过回调监测任务状态

1、回调函数 回调函数定义&#xff1a;把函数的指针或者地址作为参数传递给另一个参数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;那么这就是一个回调的过程&#xff0c;这个被回调的函数就是回调函数。回调函数不是由该函数的实现方直接调用&#xff0c;而…

反转二叉树(力扣226)

解题思路&#xff1a;用队列进行前序遍历的同时把节点的左节点和右节点交换 具体代码如下&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if (root NULL) return root;swap(root->left, root->right); // 中invertTree(root->left)…

oracle 数据库 迁移 mysql

将 Oracle 数据库迁移到 MySQL 是一项复杂的任务&#xff0c;因为这两种数据库管理系统具有不同的架构、语法和功能。下面是一个基本的迁移步骤&#xff0c;供你参考&#xff1a; 步骤一&#xff1a;评估和准备工作 1.评估数据库结构&#xff1a;仔细分析 Oracle 数据库的结构…

让15万的车也配激光雷达,速腾发布中长距「千元机」MX

‍作者 |老缅 编辑 |德新 4月15日&#xff0c;国内头部激光雷达公司速腾聚创发布了新一代中长距激光雷达MX。 相比较其产品配置&#xff0c;最令人惊喜的是它的价格。 「MX将以低于200美元的价格作为基础&#xff0c;实现第一个项目的量产。」速腾聚创CEO邱纯潮在发布会现场…

Python连接Oracle数据库问题解决及Linux服务器操作知识

背景说明 最近在做一个视频分析的项目&#xff0c;然后需要将视频分析的数据写入到oracle数据库&#xff0c;直接在服务器上测试数据库连接的时候出现了这个bug提示&#xff0c;自己通过不断的研究探讨&#xff0c;最终把这个问题成功进行了解决&#xff0c;在这里进行一下记录…

Avi Wigderson:理论计算机科学的巨人

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f40d; Python工具 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 A…

LeetCode-热题100:98. 验证二叉搜索树

题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#x…

Java项目:基于SSM框架实现的心遗非遗文创电商平台(源码+数据库)

一、项目简介 本项目是一套基于SSM框架实现的心遗非遗文创电商平台 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

Linux_CentOS7/8系统 - 关闭图形界面新增用户机制手册

Linux_CentOS7/8系统 - 关闭图形界面新增用户机制手册 在系统完成图形界面安装后重新启动后第一次登入&#xff0c;在图形界面会有新增用户页面&#xff0c;那如果取消关闭可以按以下操作&#xff1a; CTRLALTF2 root账号登录 yum remove gnome-initial-setup -y init 3 init …