JVM内存管理<一>:Java内存异常问题排查

一、 内存溢出问题的排查

1. 使用工具 - jdk自带

  • jmap
  • visualvm

2. 流程

  1. 堆转储:
    (1) 方法一:程序运行时,采用:jmap -dump:format=b,file=d:\\data\\xxlJob.hprof 23300 进行堆文件的转储
    (2) 方法二:在内存溢出的时候,打印堆转储文件
java 复制代码
-XX:+HeapDumpOnOutOfMemoryError           # 开启OOM时自动转储堆
-XX:HeapDumpPath=/path/to/dump/dir/       # 指定堆转储文件路径
-XX:OnOutOfMemoryError="command args"     # OOM时执行外部命令
  1. 导入visualVM中
    文件->装入->选择堆转储文件
  1. 分析:自定义的对象的数量、大小都不应该太大
    a. 通过大小、对象数量进行排序,查看靠前的对象是否存在自定义的对象
    b. 通过名称排序,查看自定义的对象中,哪个对象最靠前

二、gc频繁问题的排查

1. 了解堆分配的策略

a. 优先分配到年轻代

b. 大对象直接分配到老年代

c. 长期存活的对象进入老年代

d. 对象担保策略:如果年轻代的对象的总容量大于了老年代的剩余容量,需要进行一次full gc

2. 频繁minor gc

原因

(1) 内存分配过小

(2) 内存泄漏

(3) 频繁的对象创建
排查和解决方案

(1)经过mimor gc之后,对象仍旧无法被清除,导致full gc:考虑内存泄漏问题,查看是否存在内存泄漏,可以通过jmap + visualvm进行排查

(2) 如果是并发高的场景:minor gc之后,考虑eden分配过小,尝试增大内存的分配量,尤其是eden区的

(3) 如果不是高并发,内存还有急速升高的情况,可能是对象创建太过频繁,或者创建了大对象导致的

总结:分配大内存 + 排查堆转储文件,查看哪个自定义对象的占用内存较大,优化代码

3. 频繁full gc

原因

(1)minor gc分配太小,导致频繁minor gc,进而对象年龄急速增加,进入老年代

(2)full gc 分配太小,空间担保机制,使得minor gc之前,需要进行full gc

(3)内存泄漏或者大对象的创建
解决方案:

(1)首先尝试分配大内存

(2)如果不行,通过排查堆转储文件,也就是使用jmap和visualvm查看较大的自定义对象

相关推荐
superman超哥11 小时前
Rust 内存泄漏检测与防范:超越所有权的内存管理挑战
开发语言·后端·rust·内存管理·rust内存泄漏
愤怒的代码11 小时前
从开发调试到生产上线:全维度 Android 内存监控与分析体系构建
android·java·kotlin
悟能不能悟11 小时前
java HttpServletRequest 设置header
java·开发语言
云栖梦泽11 小时前
易语言运维自动化:中小微企业的「数字化运维瑞士军刀」
开发语言
悟空码字11 小时前
SpringBoot整合FFmpeg,打造你的专属视频处理工厂
java·spring boot·后端
刘975311 小时前
【第23天】23c#今日小结
开发语言·c#
独自归家的兔11 小时前
Spring Boot 版本怎么选?2/3/4 深度对比 + 迁移避坑指南(含 Java 8→21 适配要点)
java·spring boot·后端
郝学胜-神的一滴11 小时前
线程同步:并行世界的秩序守护者
java·linux·开发语言·c++·程序人生
superman超哥11 小时前
Rust 移动语义(Move Semantics)的工作原理:零成本所有权转移的深度解析
开发语言·后端·rust·工作原理·深度解析·rust移动语义·move semantics
青茶36011 小时前
【js教程】如何用jq的js方法获取url链接上的参数值?
开发语言·前端·javascript