解决Bug之路:记一次内存溢出问题的查找

时间:2024-04-09 17:07:34

JVM内存溢出的问题定位一直是个比较棘手的问题,日常开发项目中出现了内存溢出的情况,针对这种情况,本次通过分析dump文件,快速定位问题,实锤Bug的源头


步骤:

1、查看日志文件

服务器内存溢出报警,通过查看日志,初步怀疑查询的数据过多,造成内存溢出。

解决Bug之路:记一次内存溢出问题的查找

 

 

 

 

 

 

 

 

2、查看weblogic启动文件的配置

查看weblogic启动文件中对jvm的配置,发现有-XX:+HeapDumpOnCtrlBreak,所以应该可以生成java进程某一时间的内存快照。

解决Bug之路:记一次内存溢出问题的查找

 

 

3、查找Heap Dump文件

在发生内存溢出时,手动生成heap dump 文件,在weblogic的domain目录下,找到heap dump文件。

解决Bug之路:记一次内存溢出问题的查找

 

 

 

4、分析Heap Dump文件

Eclipse下载MAT(Memory Analyzer Tool )插件,对heap dump文件进行分析。找到消耗内存比较大的线程,发现数据库查出大量数据,放到集合中。

解决Bug之路:记一次内存溢出问题的查找

 

 

通过分析dump文件,可以定位到问题代码的具体位置,并能获取当时具体的实例对象,也可以查看对象中的具体数据,针对问题,快速解决。

 

总结:

Heap Dump 概述

Heap Dump 是 Java进程所使用的内存情况在某一时间的一次快照。以文件的形式持久化到磁盘中。 
Heap Dump的格式有很多种,而且不同的格式包含的信息也可能不一样。但总的来说,Heap Dump一般都包含了一个堆中的Java Objects, Class等基本信息。同时,当你在执行一个转储操作时,往往会触发一次GC,所以你转储得到的文件里包含的信息通常是有效的内容(包含比较少,或没有垃圾对象了) 。

Heap Dump 包含的信息

所有的对象信息 :对象的类信息、字段信息、原生值(int, long等)及引用值

所有的类信息 :类加载器、类名、超类及静态字段

垃圾回收的根对象 :根对象是指那些可以直接被虚拟机触及的对象

线程栈及局部变量 :包含了转储时刻的线程调用栈信息和栈帧中的局部变量信息

Heap Dump 获取方式

通过JVM 参数获取 dump 文件

 -XX:+HeapDumpOnOutOfMemoryError

当OutOfMemoryError发生时自动生成 Heap Dump 文件

-XX:+HeapDumpOnCtrlBreak 

交互式获取dump。在控制台按下快捷键Ctrl + Break时,JVM就会转存一下堆快照。

-XX:+HeapDumpBeforeFullGC 

当 JVM 执行 FullGC 前执行 dump。Full GC 是清理整个堆空间—包括年轻代和永久代。

-XX:+HeapDumpAfterFullGC

当 JVM 执行 FullGC 后执行 dump

-XX:HeapDumpPath=E:\java-heap\claim\heapdump${current_date}.hprof

指定 dump 文件存储路径。

注意:JVM 生成 Heap Dump 的时候,虚拟机是暂停一切服务的。

分析dump文件工具:

  eclipse插件Memory Analyzer Tool