首页 > 其他分享 >dump文件分析OOM及线程堆栈

dump文件分析OOM及线程堆栈

时间:2024-03-27 23:46:19浏览次数:17  
标签:文件 java dump OOM ArrayList hprof 线程

OutOfMemoryError (OOM)

如果项目报错: OutOfMemoryError: Java heap space,说明堆内存空间(Heap Space)中没有足够的空间来分配对象了。
一旦发生 OOM,系统有可能不可用,或者频繁重启。属于非常严重的问题。

OOM 的解决方法一:

比较简单粗暴的一种做法,是增大堆内存空间。
在 项目启动时,调大 -Xms 和 -Xmx 。
-Xms 参数用于设置JVM的初始堆内存大小,而-Xmx参数用于设置JVM的最大堆内存大小。

-Xms1024m  -Xmx2048m

OOM 的解决方法二:

-Xms 和 -Xmx 哪怕调大了,如果没有找到根本的原因,大对象不断创建,不断地占用堆内存空间,还是有可能会继续 OOM。

可以设置在发生 OOM 时自动 dump 文件,保存到指定的文件。
dump文件是进程的内存镜像,可以通过分析 dump 文件,找到导致 OOM 的代码。

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof

oom 代码示例:

不断循环,不断创建对象,占用堆内存空间,模拟 OOM 的场景。

public class OomTest {

    public static void main(String[] args)  {
        createObject();
    }

    /**
     * 不断循环,不断创建对象,模拟 OOM 的场景
     *
     */
    public static void createObject()  {
        List<OomObject> oomList =new ArrayList<>();
        while (true) {
            OomObject oomObject = new OomObject();
            oomList.add(oomObject);
        }
    }

}

添加 jvm 相关启动参数( Vm option ) :

  • 点击 Edit Configurations:
    在这里插入图片描述

  • 点击 Modify options, 选择 Add Vm Options :

在这里插入图片描述

启动参数( Vm option ) 如下:

添加启动参数,设置最大内存为 8m,模拟 OOM 的场景。

HeapDumpOnOutOfMemoryError 表示在发生 OOM 时会自动 dump 。

-Xms4m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/heapdump.hprof

运行代码:

结果如下:

Connected to the target VM, address: '127.0.0.1:63909', transport: 'socket'
java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:/heapdump.hprof ...
Heap dump file created [31923817 bytes in 0.263 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3210)
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:261)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
	at java.util.ArrayList.add(ArrayList.java:458)
	at com.example.demo.oom.OomTest.createObject(OomTest.java:21)
	at com.example.demo.oom.OomTest.main(OomTest.java:14)

可以看到 :

java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:/heapdump.hprof ...

这里的 D:/heapdump.hprof ,就是 dump 文件保存的路径。

打开 dump 文件

点击 Profiler ,再点击 Open Snapshot ,选择 上面的 dump 文件 D:/heapdump.hprof 。

在这里插入图片描述

点击 Biggest Objects, 可以看到 OomObject 这个对象占用了最大的内存。

结果如下:

在这里插入图片描述

使用 jdk 自带的 java visualvm ,分析dump文件, 找到 导致OOM 的代码

另外,也可以下载 MAT(Memory Analyzer Tool) 来分析 dump 文件。
此处使用 jdk 自带的 java visualvm 来分析 dump 文件, 找到 导致OOM 的代码 。

在 jdk 的 bin 文件中,找到 jvisualvm.exe 。点击即可运行。

在这里插入图片描述

  • 装入 hprof 后缀的 dump 文件 :

打开 VisualVM 后,点击左上角的图标 ,装入, 文件名选择 之前的 dump 文件 D:/heapdump.hprof 。

文件类型 选择 【堆Dump(*.hprof)】。

在这里插入图片描述

可以看到,在出现 OutOfMemoryError 异常错误时进行了堆转储,导致 OutOfMemoryError 异常错误的线程 是哪一个。

点击这个线程,即可显示导致OOM的线程堆栈。

在这里插入图片描述

  • 可以看到导致OOM的具体代码是类的哪一行:

在这里插入图片描述

标签:文件,java,dump,OOM,ArrayList,hprof,线程
From: https://www.cnblogs.com/expiator/p/18100578

相关文章

  • 定时备份mysql数据库数据--mysqldump版
    前言:mysqldump是MySQL自带的逻辑备份工具,可以将整个数据库或者指定的表格导出为一个SQL脚本文件,可以用于数据库备份。1、编写shell脚本#备份文件保存路径backup_dir=/data/mysqlbackup#当前时间current_time=`date+%Y-%m-%d-%H-%M-%S`#当前年份year=`date+%Y`#......
  • 并发锁与线程池(一)
    1.什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在多核或多CPU系统中,线程可以被调度到不同的核心上执行,从而实现真正......
  • ThreadPool-线程池使用及原理
    1.线程池使用方式示例代码://一池N线程Executors.newFixedThreadPool(int)//一个任务一个任务执行,一池一线程Executors.newSingleThreadExecutorO//线程池根据需求创建线程,可扩容,遇强则强Executors.newCachedThreadPool()//自定义线程池方式newThreadPoolExec......
  • 【性能测试】线程数、并发数和TPS的关系
    项目背景某通信产品在提测阶段,领导要求支持1w人同时在线,支持1000并发,去测吧理解需求“支持1w人同时在线,支持1000并发”“1w人同时在线”这个理解起来简单一些,对于即时通讯产品来说,就是1w个长链接,直接写脚本建立长链接就行。“支持1000并发”这里就产生歧义了:1、什么功......
  • 线程池
    线程池引入一个线程完成一项任务所需时间为:创建线程时间-Time1线程中执行任务的时间-Time2销毁线程时间-Time3为什么需要线程池线程池技术正是关注如何缩短或调整Time1和Time3的时间,从而提高程序的性能。项目中可以把Time1,T3分别安排在项目的启动和结束的时......
  • 创建与启动线程之二(继承Thread类)(实现Runnable接口)
    1.概述java的JVM允许程序运行多个线程.使用java.lang.Thread来表示线程.一个线程都直接或间接的继承于Thread类,即每个线程的对象要么是Thread的实例,要么是其子类的实例.2.Thread类的特性每个线程都是通过某个特定的Thread对象的run方法来完成操作的,run()被称为线程执行体.......
  • java声明不同线程池
    声明一个静态线程池publicstaticfinalExecutorServicePOOL;privatestaticThreadFactorynamedThreadFactory=newThreadFactoryBuilder().setNameFormat("COMMON-POOL-%d").build();static{POOL=newThreadPoolExecutor(20,40,300,......
  • 生产大文件下载导致 OOM,顺藤摸瓜拿下
    上周遇到了生产环境OOM的问题,找了一番之后基本定位了是大文件下载导致的问题,于是在网上搜罗了一番文章,下面分享一篇优质的解决方案,整个排查思路非常清晰,小白可以直接对照着来排查。事故发生上周五下午运营人员反馈,笔者所负责的后台系统从14点以后就卡卡的,虽然页面能够正常加......
  • spring+struts 配置和管理线程池
    <!--定义线程池--><beanid="taskExecutor"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><propertyname="corePoolSize"value="5"/><propertyname="maxPoolSi......
  • linux 线程的一些简答概念
    基本概念1.临界资源:多线程执行流共享的资源2.临界区:访问临界资源的代码3.原子性:只有完成和未完成两种状态。4.互斥:同一时间只能允许一个线程访问临界资源,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。可以加锁实现。加锁可以保证单个线程对临界......