驻马店市网站建设_网站建设公司_CSS_seo优化
2025/12/30 9:20:13 网站建设 项目流程

gc的老年代内存高居不下,导致最后full gc的发生,我们需要通过分析gc dump文件来解决biggest objects过多的问题

生成dump文件

在keycloak容器中安装轻量级工具

microdnf install -y wget
microdnf install -y procps-ng #包含ps命令
ps -aux # 找到keycloak的pid,默认是712
wget  https://github.com/apangin/jattach/releases/download/v2.0/jattach
chmod +x jattach
# 使用jattach执行内存命令
./jattach 712 dumpheap /tmp/heap.hprof

下载生成的hprof文件,使用jprofile分析它

我们可以从biggest objects里面,查看哪些大对象没有被释放,或者频繁被创建

HProf文件和Dump文件

1. Dump 文件(转储文件)

广义概念:程序在某个时间点的状态快照。

Java 中的 Dump 文件主要类型

类型 描述 常用扩展名
Heap Dump JVM 堆内存快照,包含所有对象实例 .hprof, .bin, .dmp
Thread Dump 线程状态快照,包含调用栈、锁信息 .tdump, .txt
Core Dump 进程崩溃时的完整内存镜像 .core, .dmp

2. HProf 文件

具体格式:Java 专用的堆转储文件格式。

特点

  • 标准格式:Oracle/OpenJDK 的标准堆转储格式
  • 二进制格式:包含完整的堆内存数据结构
  • 包含内容
    • 所有对象实例及其数据
    • 对象之间的引用关系
    • 类元数据(Class metadata)
    • GC Root 引用链
    • 静态变量

3. 两者关系

Dump文件(概念)
├── Heap Dump(堆转储)
│   ├── HProf 格式(标准格式)
│   ├── JProfiler 格式(.snapshot)
│   └── YourKit 格式(.snapshot)
├── Thread Dump(线程转储)
└── Core Dump(核心转储)

4. 生成方式对比

Heap Dump (HProf) 生成

# 1. 使用 jmap 命令(最常用)
jmap -dump:format=b,file=heap.hprof <pid># 2. 使用 jcmd 命令
jcmd <pid> GC.heap_dump /path/to/heap.hprof# 3. JVM 启动参数(内存溢出时自动生成)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dumps# 4. 使用 VisualVM、JConsole 等工具

Thread Dump 生成

# 1. 使用 jstack 命令
jstack <pid> > thread.dump# 2. 使用 jcmd
jcmd <pid> Thread.print > thread.dump# 3. 发送信号
kill -3 <pid>  # 输出到标准输出

5. 文件结构解析

HProf 文件内容结构

文件头
↓
记录类型1 (如:UTF8字符串表)
↓
记录类型2 (如:类加载信息)
↓
记录类型3 (如:实例数据)
↓
记录类型4 (如:对象引用)
↓
...

关键数据段

  1. 字符串表 - 所有字符串常量的映射
  2. 类信息 - 加载的类、父类、接口
  3. 实例数据 - 每个对象实例的字段值
  4. 对象数组 - 数组类型和元素
  5. 根引用 - GC Roots 集合
  6. 原始数据 - 堆栈帧、本地变量等

6. 分析方法工具

分析 HProf 文件的工具

工具 特点 适用场景
Eclipse MAT 功能强大,内存分析专业 深入内存泄漏分析
VisualVM JDK 自带,轻量级 快速查看概览
JProfiler 商业工具,可视化好 性能分析和监控
YourKit 商业工具,CPU/Memory分析 生产环境分析
Java Mission Control Oracle 官方工具 Flight Recorder 数据分析

示例:使用 MAT 分析步骤

# 1. 生成转储文件
jmap -dump:live,format=b,file=keycloak.hprof <pid># 2. 用 MAT 打开,常见视图:
- Histogram(直方图): 按类统计对象数量
- Dominator Tree(支配树): 找出内存占用最大的对象
- Leak Suspects(泄漏嫌疑): 自动分析疑似泄漏
- Path to GC Roots(到GC根的路径): 查看对象引用链

7. 实际案例分析

你遇到的 QueryPlanCache 问题分析

// HProf 分析中可能看到:
org.hibernate.engine.query.spi.QueryPlanCache
├── queryPlanCache (ConcurrentHashMap)
│   ├── key: "from User where realmId = ? order by createdTimestamp"
│   ├── value: QueryPlan对象 (包含解析后的SQL、参数映射等)
│   └── size: 可能数千个条目
└── parameterMetadataCache└── 存储参数元数据

文件大小参考

  • 小型应用:几百 MB
  • 中型应用(如 Keycloak):1-4 GB
  • 大型应用:10 GB+

8. 使用技巧

减小 HProf 文件大小

# 1. 只转储存活对象(推荐)
jmap -dump:live,format=b,file=heap.hprof <pid># 2. 过滤不需要的内容
# 使用MAT的OQL或过滤器功能# 3. 压缩存储
jmap -dump:live,format=b,file=heap.hprof.gz <pid>

自动化分析脚本

#!/bin/bash
PID=$(jps | grep keycloak | awk '{print $1}')
TIMESTAMP=$(date +%Y%m%d_%H%M%S)# 生成堆转储
jmap -dump:live,format=b,file=/dump/keycloak_${TIMESTAMP}.hprof $PID# 生成线程转储
jstack $PID > /dump/thread_${TIMESTAMP}.dump# 基本分析
echo "=== 堆转储生成完成 ==="
echo "文件: /dump/keycloak_${TIMESTAMP}.hprof"
echo "大小: $(du -h /dump/keycloak_${TIMESTAMP}.hprof | cut -f1)"

9. 注意事项

  1. 性能影响:生成堆转储会暂停 JVM(Stop-The-World),生产环境谨慎使用
  2. 磁盘空间:确保有足够的磁盘空间(通常是堆内存的1-1.5倍)
  3. 安全考虑:转储文件可能包含敏感数据(如密码、密钥)
  4. 版本兼容性:HProf 文件与 JVM 版本相关,高版本工具可分析低版本文件

10. 最佳实践

  1. 定期收集基线:在应用稳定时收集作为对比基准
  2. 配置自动转储:配置 OOM 时自动生成转储
  3. 保留多个时间点:对于内存泄漏,保留多个时间点的转储对比
  4. 配合日志分析:转储文件结合 GC 日志、应用日志分析

总结:HProf 是 Java 堆转储的标准格式文件,属于 Dump 文件的一种。通过分析这种文件,可以定位内存泄漏、优化内存使用,就像你发现的 QueryPlanCache 问题一样。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询