面试题集中营—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] 
Heappar 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 1056768Kclass 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] 
HeapPSYoungGen      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 1056768Kclass 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统计信息

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 2024.1 配置 AspectJ环境

最近Java课设在学习AspectJ&#xff0c;做PPT顺便写一个博客 下载包 首先去AspectJ官网下载一个JAR包并安装 安装完最后可以按照他的建议配置一下 然后找到AspectJ的安装位置的lib目录&#xff0c;把三个包拷到自己项目中的lib目录下 由于最新版的IDEA已经不支持AspectJ了 所…

mysql基础1——数据存储

mysql数据存储 共有4步 1&#xff09;创建数据库 2)确认字段 3)创建数据表 4)插入数据 1&#xff09;创建数据库 从系统架构看mysql数据库系统依次是数据库服务器&#xff0c;数据库&#xff0c;数据表和数据表的行与列 安装程序-->安装了数据库服务器 所有要做的第…

OpenHarmony开发实例:【 待办事项TodoList】

简介 TodoList应用是基于OpenHarmony SDK开发的安装在润和HiSpark Taurus AI Camera(Hi3516d)开发板标准系统上的应用&#xff1b;应用主要功能是以列表的形式&#xff0c;展示需要完成的日程&#xff1b;通过本demo可以学习到 JS UI 框架List使用&#xff1b; 运行效果 样例…

前端三剑客 HTML+CSS+JavaScript ③ HTML标准结构

生活没有任何意义&#xff0c;这就是活着的理由&#xff0c;而且是唯一的理由 —— 24.4.22 一、HTML注释 1.特点 注释的内容会被浏览器所忽略&#xff0c;不会呈现到页面中&#xff0c;但源代码中依然可见 2.作用 对代码进行解释和说明 3.写法 <!-- xxxxx --> <html&…

上位机图像处理和嵌入式模块部署(树莓派4b使用pcl点云库)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 图像处理&#xff0c;大家都知道它有显著的优点和缺点。优点就是分辨率高&#xff0c;信息丰富。缺点就是&#xff0c;整个图像本身没有深度信息。…

高效可扩展,使用Dask进行大数据分析

大家好&#xff0c;Dask技术作为并行计算领域的创新力量&#xff0c;正在重塑大数据的处理模式。这项开源项目为Python语言带来了强大的并行计算能力&#xff0c;突破了传统数据处理在扩展性和性能上的瓶颈。 本文将介绍Dask的发展历程、架构设计&#xff0c;并分析其在大数据…

Nacos服务注册中心

1.引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>2.application.properties中配置 # 应用名称 spring.application.namenacos-aserver…

接收区块链的CCF会议--SecureComm 2024 截止5.10 附录用率

会议名称&#xff1a;SecureComm CCF等级&#xff1a;CCF C类会议 类别&#xff1a;网络与信息安全 录用率&#xff1a;2022年录用率33%&#xff08;43/130) Topics Security and privacy in computer networks (e.g., wired, wireless, mobile, hybrid, sensor, vehicular,…

UI5:面向企业级应用的JavaScript框架

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ng反向代理 conf配置

log_format szxw_timed_combined $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time $upstream_response_time;#外部转发 …

15.Nacos服务分级存储模型

服务跨集群调用问题&#xff1a; 服务调用尽可能的选择本地集群的服务&#xff0c;跨集群调用延迟较高。 本地集群不可访问的情况下&#xff0c;再去访问其他集群。 如何配置集群的实例属性&#xff1a; spring: cloud:nacos:server-addr: localhost:8848 #nacos服务端地址d…

findImg找图工具

findImg 安装 npm install findImg -g 启动 findImg run 介绍 找出当前目录下的所有图片&#xff08;包括svg的symbol格式&#xff09;在浏览器中显示出来 源码 https://github.com/HuXin957/find-img 场景 例如前端项目中的img目录&#xff0c;大家都在往里面放图片&#xff…

java接口自动化测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

那些早期的iax和SIP软电话软件界面,看看你见过几个?

目录 一些iax/sip软电话UI图片SIP软电话的界面怎么设计SIP软电话的功能有哪些 早期voip发展中&#xff0c;很多公司开发了自己的SIP软电话&#xff0c;有些已经不存在了&#xff0c;有些还在使用中&#xff0c;比如X-Lite&#xff0c;Zoiper等等&#xff0c;我们一起看看这些早…

lvgl图形化设计工具GUI Guider结合使用

前言 上篇博客整合了lvgl到项目中&#xff0c;采用的是自己编写源码的方式&#xff0c;实现了个简单的界面。实际过程中一般情况开发界面都借助设计工具&#xff0c;这里使用的是gui guider来进行示例记录 项目结构&#xff08;生成代码路径依然放到项目路径下&#xff09; C…

实验2 组合逻辑电路与时序逻辑电路设计

实验目的: 1.构建基于verilog语言的组合逻辑电路和时序逻辑电路; 2.掌握verilog语言的电路设计技巧。 3.完成如下功能:加法器、译码器、多路选择器、计数器、移位寄存器等。 实验内容及步骤: 一、实验原理 原理图文件《数字系统设计_sch.pdf》,找到如下两个部分: 图…

一文扫盲(5):实验室管理系统的界面设计

本次带来第5期&#xff1a;实验室管理系统的设计&#xff0c;从系统定义、功能模块、界面构成和设计着力点四个方面讲解&#xff0c;大千UI工场愿意持续和大家分享&#xff0c;欢迎关注、点赞、转发。 一、什么是实验室管理系统 实验室管理系统是一种用于管理和监控实验室运作…

nodejs版本过高导致vue-cli无法启动的解决方案

目录 前言异常现象解决方案总结 前言 之前使用软件管家升级了Nodejs&#xff0c;今天在运行Vue项目的时候老是报错&#xff0c;查了很多资料&#xff0c;最后确定是Nodejs版本过高导致的。 异常现象 E:\project\ry\RuoYi-Cloud\ruoyi-ui>npm run dev> ruoyi3.6.4 dev …

13-LINUX--消息队列

一.消息队列 1.消息队列&#xff1a;消息队列为一个进程向另一个进程发送一个数据块提供了条件&#xff0c;每个数据块会包含一个类型。 2.相关函数 1>.msgget(key_t key,int msgflg) : 创建消息队列 2>. msgsnd&#xff1a;把消息添加到消息队列 3>.msgrcv &#xf…

CSS布局 Flex 和 Grid

在 CSS 中&#xff0c;理解 flex 和 Grid 布局非常重要&#xff0c;今天把这两个重要知识点回顾一下。 Flexbox 弹性盒子布局 弹性布局支持 flex、inline-flex&#xff0c;支持块和内联。 容器 轴的概念&#xff0c;在 Flexbox&#xff0c;有主轴和侧轴的概念&#xff0c;轴…