当前位置: 首页 > news >正文

jvm内存泄漏的排查tips总结

以下是对这篇原文的总结,部分内容不够详细,请参考原文地址:https://juejin.cn/post/7255634554987020343

内存问题排查方法论

1. 问题定位流程

  • 确定进程:使用 ps aux --sort=-%mem 找出内存占用最高的进程
  • 分层排查:按照堆内 → 堆外的顺序逐步分析
  • 量化分析:通过计算得出具体的内存占用分布

2. 堆内存分析技巧

# 查看堆内存详情
jcmd <pid> GC.heap_info# 查看真实物理内存占用
pmap -X <pid>

image

3. 堆外内存分析技巧

# 使用Arthas快速查看各内存区域
memory# 计算公式
堆外物理内存 = 总占用物理内存 - heap占用的物理内存

jcmd GC.heap_info
image
heap:启动参数里指定了Xmx是4G,从命令结果也可以看出约等于 new generation 1.8G + old geration 2G。
Metaspace: committed 约0.1G左右
通过pmap命令可以看到最真实的JVM heap的物理内存的占有量,因为Heap本质是一个内存池,池子的总大小4G,但是实际物理内存一般达不到4G,而Heap的used也只是池子中使用部分的内存。所以还是要通过操作系统的pmap来查询:
image
如上图,JVM heap是4G的虚拟内存,启动物理内存约占用3144764K即约3G,50M左右置换到了swap空间。
所以heap实际占用约3G。

4. JNI Memory泄漏排查

方向一:gperftools工具分析,查堆栈

# 安装工具
yum install gperftools gperftools-devel graphviz ghostscript# 设置环境变量
export LD_PRELOAD=/usr/lib64/libtcmalloc.so
export HEAPPROFILE=/home/admin/gperftools/heap/hprof# 启动app。。。
# kill app,再运行app_start.sh# 生成对比报告
pprof --pdf --base=heap_before.heap java heap_after.heap > mem-diff.pdf

例如:最大头的是Java_java_util_zip_Inflater_inflateBytes函数在申请堆外内存,共680M,占比680M
image

方向二:内存块分析,看内存块内容

# 查看内存块分布
(pmap -X <pid> | head -2; pmap -X <pid> | awk 'NR>2' | sort -nr -k6) > pmap.log# dump内存块内容
gdb --batch --pid <pid> --ex 'dump memory 103.dump 0x7f8a78000000 0x7f8a7c000000'# 查看内存数据
strings 103.dump

5. 调用栈定位技巧

# 持续打印线程堆栈
while true; do jstack <pid> | grep -A 20 -B 5 "inflateBytes"; sleep 1; done# 或使用arthas拦截方法调用
stack java.util.zip.Inflater inflate

6. GC验证方法

# 手动触发FullGC并查看对象分布
jmap -histo:live <pid>

7. ptmalloc2内存碎片处理

手动释放内存

# 调用malloc_trim释放碎片内存
gdb --batch --pid <pid> --ex 'call malloc_trim()'

优化参数

export MALLOC_ARENA_MAX=8
export MALLOC_MMAP_THRESHOLD_=131072 
export MALLOC_TRIM_THRESHOLD_=131072 
export MALLOC_TOP_PAD_=131072 
export MALLOC_MMAP_MAX_=65536

8. 解决方案选择

推荐方案:替换内存分配器

# 使用jemalloc或tcmalloc
export LD_PRELOAD=/usr/lib64/libjemalloc.so
# 或
export LD_PRELOAD=/usr/lib64/libtcmalloc.so

业务层面优化

  • 修改Kafka压缩算法:gzip → Snappy/LZ4
  • 避免使用JVM的gzip相关JNI调用
  • 其他

9. 关键排查命令总结

ps aux --sort=-%mem          # 找出内存大户进程
jcmd <pid> GC.heap_info      # 查看堆内存
pmap -X <pid>                # 查看真实内存分布  
jstack <pid>                 # 查看线程堆栈
jmap -histo:live <pid>       # 触发GC并查看对象
gdb --batch --pid <pid> --ex 'call malloc_trim()'  # 释放碎片内存

10. 注意事项

  • malloc_trim() 有极小概率导致JVM Crash,使用需谨慎
  • 使用gperftools时,tcmalloc会间接解决问题,影响问题复现
  • 64M内存块是ptmalloc2内存碎片的典型特征
  • 不同内存分配器适用场景不同:小内存高并发用TCMalloc,通用场景用ptmalloc2
http://www.wxhsa.cn/company.asp?id=6695

相关文章:

  • IPA
  • Chromium历史版本下载方式
  • 【ACM出版】第三届物联网与云计算技术国际学术会议 (IoTCCT 2025)
  • 2025年最全 Wiki 管理工具测评:ONES、Confluence、Notion......哪个更适合你?
  • 鼠你爱称重
  • 详细介绍:用户争夺与智能管理:定制开发开源AI智能名片S2B2C商城小程序的战略价值与实践路径
  • PlorarD(WEB中等)
  • 神经网络稀疏化设计构架方式和原理深度解析
  • 天下拍拍卖系统:二方系统也能扩展三方平台功能
  • express使用redis
  • day07 课程
  • 111
  • 排序实现java - 教程
  • .net core 发布到 iis 步骤
  • kylin SP2安装mysql8.4.5
  • 微信社群机器人接口
  • C++的枚举类
  • Revit二次开发 钢筋生成API(一)
  • 方法
  • 详细介绍:PHP基础-语法初步(第七天)
  • 如何通过Python SDK 删除 Collection
  • maven项目连接DM数据库和基本sql使用
  • 【中国计算机学会CCF主办】第六届人工智能、大数据与算法国际学术会议(CAIBDA 2026)
  • 图片 - voasem
  • 面试时让你设计一个“朋友圈点赞”功能测试,如何回答才出彩?
  • 企训宝教育培训微信小程序系统
  • Inventor Professional 2026.1.1 产品设计与工程制图
  • 叮当计步微信小程序系统
  • fetch-event-source踩坑sse(getReader)后续 IOS全量返回问题
  • P12508 「ROI 2025 Day2」程序员的日常