JProfile 分析OOM hprof文件

article/2025/10/13 21:45:15

JProfile 分析OOM OutOfMemoryError

1.JVM组成

首先要明白JVM组成

  1. 方法区-非堆 Method Area、No-Heap
  2. Java栈-虚拟机栈 VM Stack、Java Stack
  3. 本地方法栈 Native Method Stack
  4. 程序计数器 Program Counter Register
  5. 堆 Heap
1.1 OOM发生在哪里?

OOM可以发生在除了程序计数器外的其他部分,包括四块:

  • 方法区(非堆)
  • Java栈
  • 本地方法栈
1.2 垃圾回收、哪里有垃圾?
  • 方法区(非堆)
1.3 基本JVM参数
参数示例描述说明
-verbose:gc控制台打印GC参数
-Xms20M初始堆大小 20M
-Xmx20M最大堆大小20M 一般情况下-Xms和-Xmx这两个值设为相同大小。因为如果不相同
-Xmn10M新生代最大可用值10M
-XX:+PrintGC触发GC时日志打印
-XX:+PrintGCDetails触发GC时日志打印详细
–XX:UseSerialGC串行回收
-XX:SurvivorRatio=2eden:from:to =2:1:1
-XX:+HeapDumpOnOutOfMemoryErroOOM时生成Dump文件
-XX:NewRatio=2新生代:老年代 = 1:2

2.堆发生OOM

2.1 代码

调整JVM参数

# -verbose:gc  控制台打印GC参数
# -Xms10M 初始堆大小
# -Xmx10M 最大堆大小 一般情况下-Xms和-Xmx这两个值设为相同大小。因为如果不相同且内存不够用时会发生内存抖动现象,影响程序运行
# -Xmn5M  新生代最大可用值5M
# -XX:+PrintGC  触发GC时日志打印
# -XX:+PrintGCDetails 触发GC时日志打印详细
# -XX:+HeapDumpOnOutOfMemoryError OOM时生成Dump文件
# -XX:SurvivorRatio=3 说明伊甸区 eden:from:to=3:1:1
-verbose:gc -Xms10M -Xmx10M -Xmn5M  -XX:PrintGC  -XX:PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=10

运行代码

package com.jzj.jvmtest.oomtest;import java.util.ArrayList;
import java.util.List;/*** 堆溢出, 只要不停的新建对象,就会堆溢出*/
public class HeapOOM {public static void main(String[] args) {System.out.print("最大内存: ");System.out.println(Runtime.getRuntime().maxMemory() / 1024 / 1024 + "MB");System.out.print("可用内存: ");System.out.println(Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB");System.out.print("已使用内存: ");System.out.println(Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB");List<HeapOOM> list = new ArrayList<>();while (true) {list.add(new HeapOOM());}}
}
2.2 OOM日志
最大内存: 18MB
可用内存: 15MB
已使用内存: 18MB
[GC (Allocation Failure) [PSYoungGen: 5595K->2040K(8192K)] 5595K->2997K(18432K), 0.0022678 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8184K->2038K(8192K)] 9141K->7231K(18432K), 0.0053117 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->6144K(8192K)] [ParOldGen: 10123K->10123K(10240K)] 16267K->16267K(18432K), [Metaspace: 3500K->3500K(1056768K)], 0.1431659 secs] [Times: user=1.41 sys=0.00, real=0.14 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->6144K(8192K)] [ParOldGen: 10124K->10124K(10240K)] 16268K->16268K(18432K), [Metaspace: 3500K->3500K(1056768K)], 0.1269467 secs] [Times: user=1.09 sys=0.00, real=0.13 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->6144K(8192K)] [ParOldGen: 10125K->10125K(10240K)] 16269K->16269K(18432K), [Metaspace: 3500K->3500K(1056768K)], 0.1402382 secs] [Times: user=1.41 sys=0.00, real=0.14 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->6144K(8192K)] [ParOldGen: 10126K->10126K(10240K)] 16270K->16270K(18432K), [Metaspace: 3500K->3500K(1056768K)], 0.1276036 secs] [Times: user=1.13 sys=0.00, real=0.13 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->6144K(8192K)] [ParOldGen: 10127K->10127K(10240K)] 16271K->16271K(18432K), [Metaspace: 3500K->3500K(1056768K)], 0.1277889 secs] [Times: user=1.24 sys=0.00, real=0.13 secs] 
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid30128.hprof ...
Heap dump file created [27909929 bytes in 0.072 secs]
[Full GC (Ergonomics) [PSYoungGen: 6144K->0K(8192K)] [ParOldGen: 10179K->762K(10240K)] 16323K->762K(18432K), [Metaspace: 3542K->3542K(1056768K)], 0.0042329 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
HeapPSYoungGen      total 8192K, used 167K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)eden space 6144K, 2% used [0x00000000ff600000,0x00000000ff629e60,0x00000000ffc00000)from space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000)to   space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000)ParOldGen       total 10240K, used 762K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)object space 10240K, 7% used [0x00000000fec00000,0x00000000fecbe9a8,0x00000000ff600000)Metaspace       used 3615K, capacity 4508K, committed 4864K, reserved 1056768Kclass space    used 394K, capacity 396K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededat com.jzj.jvmtest.oomtest.HeapOOM.main(HeapOOM.java:20)Process finished with exit code 1
2.3 日志分析
Eden-From-To分析

-XX:SurvivorRatio=3 说明2个Survivor 与Eden区的 大小比值为 2:3
以-Xmn = 10M 为例 10*1024KB / (2+3) = 2048KB/每一份
Eden有 3份也就是6M,From Survivor有2M,To Survivor有2M
对比日志

 PSYoungGen      total 8192K, used 167K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)eden space 6144K, 2% used [0x00000000ff600000,0x00000000ff629e60,0x00000000ffc00000) -6Mfrom space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000) -2Mto   space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000) -2M
2.4 报错日志
Event: 5.271 GC heap after
Heap after GC invocations=39 (full 37):PSYoungGen      total 8192K, used 6143K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)eden space 6144K, 99% used [0x00000000ff600000,0x00000000ffbffff8,0x00000000ffc00000)from space 2048K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x0000000100000000)to   space 2048K, 0% used [0x00000000ffc00000,0x00000000ffc00000,0x00000000ffe00000)ParOldGen       total 10240K, used 10140K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)object space 10240K, 99% used [0x00000000fec00000,0x00000000ff5e70f0,0x00000000ff600000)Metaspace       used 3500K, capacity 4500K, committed 4864K, reserved 1056768Kclass space    used 382K, capacity 388K, committed 512K, reserved 1048576K
}

eden space 6144K, 99% used [0x00000000ff600000,0x00000000ffbffff8,0x00000000ffc00000) Eden区 占用99%说明程序在不停的新建对象,一直把Eden 占满了 ,而且 触发YongGC后,看一下YGC的日志

[GC (Allocation Failure) [PSYoungGen: 5595K->2040K(8192K)] 5595K->2997K(18432K), 0.0022678 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

PSYoungGen: 5595K->2040K(8192K)
年轻代垃圾回收前5595K,年轻代回收后 2040K, 年轻代总大小一共8192K
整个堆回收前大小5595K,整个堆回收后2997K,整个堆一共大小18432K~=18M

3.JProfile 分析Dump文件

3.1 打开JProfile

我们找到发生OOM时候,的Dump文件,然后用JProfile打开
在这里插入图片描述

3.2 找到最大的对象

最大的对象很有可能是当前OOM溢出的原因,可以看到最大的对象时HeapOOM这个对象,JVM中有81W个这样的对象
在这里插入图片描述

3.3 找到代码出错的位置

选中当前对象,右键 -> Use selected Objects
在这里插入图片描述
点击OK
在这里插入图片描述
选中 Incoming references
在这里插入图片描述
点击 show more
在这里插入图片描述

3.4 定位到代码行号

可以看到 com.jzj.jvmtest.oomtest.HeapOOM.main(java.lang.String[ ]) (line: 20)
Main函数的 20行 进行了ArrayList.add 操作 ,导致OOM
在这里插入图片描述


http://chatgpt.dhexx.cn/article/ZDebRhFy.shtml

相关文章

java如何打开hprof_hprof是什么文件?如何打开hprof?

hprof是什么文件&#xff1f;如何打开hprof&#xff1f; 发布时间&#xff1a;2020-03-26 17:35:24 来源&#xff1a;亿速云 阅读&#xff1a;1195 作者&#xff1a;小新 hprof是什么文件&#xff1f;如何打开hprof&#xff1f;很多人都不太了解&#xff0c;今天小编为了让大家…

linux命令生成hprof文件,Android平台生成任意进程的hprof文件

一、知识介绍 1.1 为什么要抓取hprof hprof文件中记录了当前进程内存的使用情况,对于一些难以解决的OOM问题,提取出对应进程的hprof文件可以很好的分析这种问题。 分析hprof的工具 Java Heap Analyzes Tool Eclipse Memory Analyzer 1.2 生成hprof指令 adb shell am dumpheap…

java hprof文件_JVM性能调优监控工具hprof使用详解

一、问题现状 现实企业级Java开发中,有时候我们会碰到下面这些问题: OutOfMemoryError,内存不足 内存泄露 线程死锁 锁争用(Lock Contention) Java进程消耗CPU过高 …… 这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深…

java hprof文件_hprof是什么文件

hprof是什么文件&#xff1f; 是java进程的内存镜像文件&#xff0c;里面包含了内存堆详细的使用信息。 最近学习深入java虚拟机的书&#xff0c;照着里面的例子跑了下。 如何打开hprof&#xff1f; 下面是demo&#xff1a;/** * VM Args&#xff1a;-Xms20m -Xmx20m -XX:HeapD…

Hprof

转载地址&#xff1a;http://geek.csdn.net/news/detail/90509 一、开发者的自测利器-Hprof命令 1. 示例演示 例子程序&#xff1a; /*** PROJECT_NAME: test* DATE: 16/7/22* CREATE BY: chao.cheng**/ public class HProfTest {public void slowMethod() {try {T…

android hprof,Android Hprof 分析

Android Studio 中的 HProf静态分析 HProf 在 Android Studio 中的展示详解&#xff0c;基于我对其的理解&#xff0c;我将其根据 heap,count,size,其他将其分成了 4 个层次。 第一层 Heap分类 Heap 共分为&#xff1a; zygote heap: 与 android zygote 进程共享的 heap image …

android中hprof文件分析

Hprof基本概念 hprof最初是由J2SE支持的一种二进制堆转储格式&#xff0c;hprof文件保存了当前java堆上所有的内存使用信息&#xff0c;能够完整的反映虚拟机当前的内存状态。 格式 Hprof文件由FixedHead和一系列的Record组成&#xff0c;Record包含字符串信息、类信息、栈信…

hprof 文件查看

https://www.jianshu.com/p/4e6e88f1d211 hprof 文件是 Java 的 内存快照文件&#xff08;Heap Profile 的缩写&#xff09;&#xff0c;格式为 java_pid*.hprof 用于分析 OOM: OutOfMemoryError(堆)内存不足错误 是 JVM 设置 -XX:HeapDumpOnOutOfMemoryError 参数时打印的内容…

Java 内存溢出(二)使用 MAT 分析 .hprof 内存映像文件

目录 一、内存溢出时自动导出 .hprof 文件二、下载安装 MAT三、启动 MAT四、MAT 分析 hprof 文件1.Overview 概览2.Leak Suspects 溢出原因猜测3.Histogram 对象实例数量排序4.Dominator Tree 支配树 .hprof 文件&#xff1a; 是 java 项目的 Heap Dump 文件&#xff0c;也叫内…

Solr文档学习--Solrj的使用

首先启动solr solr.cmd startSolrClient 主要通过SolrClient来连接到Solr服务器 SolrClient有4个实现类 CloudSolrClient SolrJ client class to communicate with SolrCloud. Instances of this class communicate with Zookeeper to discover Solr endpoints for SolrClou…

solrj 对solr 的操作

使用SolrJ操作Solr会比利用httpClient来操作Solr要简单。SolrJ是封装了httpClient方法&#xff0c;来操作solr的API的。SolrJ底层还是通过使用httpClient中的方法来完成Solr的操作。 1、 首先&#xff0c;你需要添加如下jar包 其中apache-solr-solrj-3.4.0.jar、slf4j-api-1.6…

SolrJ的使用

CommonsHttpSolrServer CommonsHttpSolrServer 使用HTTPClient 和solr服务器进行通信。 Java代码 String url "http://localhost:8983/solr"; SolrServer server new CommonsHttpSolrServer( url ); String url "http://localhost:8983/solr";Sol…

sorl

solr&#xff1a; 层面搜索、命中醒目显示并且支持多种输出格式&#xff08;包括 XML/XSLT 和 JSON 格式&#xff09;&#xff0c;Solr 可以阅读和使用构建到其他 Lucene 应用程序中的索引。 安装&#xff1a;http://blog.csdn.net/millery22/article/details/51446014 对外提…

Solr和Solrj的使用

Solr(4.10.3)&Solrj 部署环境 1.拷贝solr solr-4.10.3\example\solr 目录到【如E:/solr/】,重命名solr为solrhome 【E:/solr/solrhome】 solrhome:solr里面有几个文件 collection1:有一个默认名称为collection1的SolrCore索引库 conf&#xff1a;SolrCore运行配置信息 co…

SolrJ的查询

1.solr是一个全文检索引擎系统,通过部署到tomcat下就可以独立运行,通过http协议对外提供全文检索服务, 就是索引和文档的正删改查服务 2. solr直接操作索引库和文档库, 我们的业务系统中可以使用solrJ(solr的客户端,就是一堆jar包)来调用solr服务端, 让solr服务端操作文档库和…

使用solrJ操作solr常用方法

既然学的是java那么肯定需要用java代码来进行对solr的操作&#xff0c;如果知道在solr后台管理界面进行增删改查等操作&#xff0c;那么用solrJ操作solr会更好理解。 solrJ介绍 solrJ是一个用来访问solr的java客户端&#xff0c;提供了索引和搜索的方法&#xff08;将一些常用…

solr快速上手:整合SolrJ实现客户端操作(九)

0. 引言 我们前面学习了solr的服务端基础操作&#xff0c;实际项目中我们还需要在客户端调用solr&#xff0c;就像调用数据库一样&#xff0c;我们可以基于solrJ来实现对solr的客户端操作 1. SolrJ简介 SolrJ 是 Solr官方提供的 Java 客户端库&#xff0c;主要用于与 Solr 服…

全文检索solr(五)Solrj的使用

什么是solrj solrj是访问Solr服务的java客户端&#xff0c;提供索引和搜索的请求方法&#xff0c;如下图&#xff1a; Solrj和图形界面操作的区别就类似于数据库中使用jdbc和mysql客户端的区别一样。 需求 使用solrj调用solr服务实现对索引库的增删改查操作。 环境准备 So…

Solr-Solrj简单使用

一、SolrJ简介 SolrJ是操作Solr的Java客户端&#xff0c;它提供了增加、修改、删除、查询Solr索引的Java接口。通过solrJ提供的API接口来操作solr服务&#xff0c;SolrJ底层是通过使用httpClient中的方法来完成Solr的操作。 二、依赖配置 <dependency><groupId>…

solrj

文章目录 1.什么是solrj?2.搭建工程2.1.导入相关jar包 3.对索引库做增删改查3.1.添加&#xff08;以实体类的方式&#xff09;添加方法 3.3.修改&#xff08;update&#xff09;3.4.删除以ID删除批量删除&#xff08;以ID&#xff09;以条件删除&#xff08;query&#xff09;…