Java应用频繁FullGC分析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: ### 一、JVM的内存分布 #### 1.1 JVM内存分布概况 ![img](https://img.alicdn.com/tfs/TB1bhRnRFXXXXa2XVXXXXXXXXXX-510-401.png) * 堆内存划分为: Eden、Survivor 和 Tenured/Old 空间 ![img](https://img.alicdn.com/tfs/TB1EVh

一、JVM的内存分布

1.1 JVM内存分布概况

img

  • 堆内存划分为: Eden、Survivor 和 Tenured/Old 空间
    img

1.2 Minor GC、Major GC、Full GC

1.3 JVM垃圾回收算法

img

二、应用的GC日志配置

2.1 应用GC日志配置

JVM的GC日志的主要参数包括如下几个:

-XX:+PrintGC 输出GC日志
-verbose:gc 示输出虚拟机中GC的详细情况
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
AI 代码解读

-verbose:gc 中参数-verbose:gc 表示输出虚拟机中GC的详细情况.

使用后输出如下:

[Full GC 168K->97K(1984K)0.0253873 secs]
AI 代码解读

解读如下:

  箭头前后的数据168K和97K分别表示垃圾收集GC前后所有存活对象使用的内存容量,说明有168K-97K=71K的对象容量被回收,括号内的数据1984K为堆内存的总容量,收集所需要的时间是0.0253873秒(这个时间在每次执行的时候会有所不同)

2.2 线上应用配置实例

img

2.2 应用GC日志分析

2017-06-02T15:10:11.930+0800: 68752.147: [GC2017-06-02T15:10:11.930+0800: 68752.147: [ParNew: 1679677K->1878K(1887488K), 0.0176620 secs] 2204253K->526489K(6753536K), 0.0178770 secs] [Times: user=0.07 sys=0.00, real=0.02 secs]
2017-06-02T15:10:18.522+0800: 68758.739: [GC2017-06-02T15:10:18.522+0800: 68758.739: [ParNew: 1679702K->2122K(1887488K), 0.0184380 secs] 2204313K->526767K(6753536K), 0.0186610 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
2017-06-02T15:10:22.812+0800: 68763.029: [GC2017-06-02T15:10:22.812+0800: 68763.030: [ParNew: 1679946K->2104K(1887488K), 0.0166490 secs] 2204591K->526796K(6753536K), 0.0168640 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
2017-06-02T15:10:29.874+0800: 68770.091: [GC2017-06-02T15:10:29.874+0800: 68770.091: [ParNew: 1679928K->1646K(1887488K), 0.0174360 secs] 2204620K->526439K(6753536K), 0.0176530 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
AI 代码解读

取倒数第一条记录分析一下各个字段都代表了什么含义

2017-06-02T15:10:29.874+0800: 68770.091: (时间)[GC(Young GC)2017-06-02T15:10:29.874+0800: 68770.091: [ParNew()使用ParNew作为年轻代的垃圾回收): 1679928K(年轻代垃圾回收前的大小)->1646K年轻代垃圾回收以后的大小)(1887488K)(年轻代的总大小), 0.0174360 secs(回收时间)]] 2204620K(堆区垃圾回收前的大小)->526439K(堆区垃圾回收后的大小)(6753536K(堆区总大小), 0.0176530 secs(回收时间)] [Times: user=0.06Young GC用户耗时) sys=0.00(Young GC系统耗时), real=0.02 secsYoung GC实际耗时)]
AI 代码解读

我们再对数据做一个简单的分析:

从最后一条GC记录中我们可以看到 Young GC回收了 1679928-1646=1678282K的内存
Heap区通过这次回收总共减少了 2204620-526439=1678181K的内存。

1678282-1678181=101K说明通过该次Young GC有101K的内存被移动到了Old Gen
AI 代码解读

我们来验证一下

在最后一次Young GC的回收以前 Old Gen的大小为526796(倒数第二条堆内存)-2104=524692 <br/>
回收以后Old Gen的内存使用为526439-1646=524793
Old Gen在该次Young GC以后内存增加了524793-524692=10K 与预计的相符
AI 代码解读

三、常见GC查看工具

img

待续

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
Java也能快速搭建AI应用?一文带你玩转Spring AI可落地性
Java语言凭借其成熟的生态与解决方案,特别是通过 Spring AI 框架,正迅速成为 AI 应用开发的新选择。本文将探讨如何利用 Spring AI Alibaba 构建在线聊天 AI 应用,并实现对其性能的全面可观测性。
列表结构与树结构转换分析与工具类封装(java版)
本文介绍了将线性列表转换为树形结构的实现方法及工具类封装。核心思路是先获取所有根节点,将其余节点作为子节点,通过递归构建每个根节点的子节点。关键在于节点需包含 `id`、`parentId` 和 `children` 三个属性。文中提供了两种封装方式:一是基于基类 `BaseTree` 的通用工具类,二是使用函数式接口实现更灵活的方式。推荐使用后者,因其避免了继承限制,更具扩展性。代码示例中使用了 Jackson 库进行 JSON 格式化输出,便于结果展示。最后总结指出,理解原理是进一步优化和封装的基础。
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
CRaC技术助力ACS上的Java应用启动加速
容器计算服务借助ACS的柔性算力特性并搭配CRaC技术极致地提升Java类应用的启动速度。
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java 也能快速搭建 AI 应用?一文带你玩转 Spring AI 可观测性
Java中的this关键字详解:深入理解与应用
本文深入解析了Java中`this`关键字的多种用法
265 9
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
61 5
【潜意识Java】了解并详细分析Java与AIGC的结合应用和使用方式
本文介绍了如何将Java与AIGC(人工智能生成内容)技术结合,实现智能文本生成。
280 5