【赵渝强老师】如何分析Java的内存溢出问题
一、什么是内存溢出?
内存溢出(OOM:out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。
在Java中,将会产生java.lang.OutOfMemoryError。看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是说,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。
二、为什么产生OOM?
为什么会没有内存了呢?原因不外乎有两点:
- 分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。
- 应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
在Java语言中,由于存在了垃圾自动回收机制,所以,我们一般不用去主动释放不用的对象所占的内存,也就是理论上来说,是不会存在“内存泄露”的。但是,如果编码不当,比如,将某个对象的引用放到了全局的Map中,虽然方法结束了,但是由于垃圾回收器会根据对象的引用情况来回收内存,导致该对象不能被及时的回收。如果该种情况出现次数多了,就会导致内存溢出,比如系统中经常使用的缓存机制。Java中的内存泄露,不同于C++中的忘了delete,往往是逻辑上的原因泄露。
三、如何分析Java OOM?
在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题。这些文件记录了JVM运行期间的内存占用、线程执行等情况,这就是我们常说的dump文件。常用的有heap dump和thread dump(也叫javacore,或java dump)。我们可以这么理解:heap dump记录内存信息的,thread dump是记录CPU信息的。这里我们重点介绍heap dump。
heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件。Heap Analyzer工具通过分析HeapDump文件,哪些对象占用了太多的堆栈空间,来发现导致内存泄露或者可能引起内存泄露的对象。
四、案例
首先,我们来开发一段Java程序。
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
int i = 0;
while (true) {
list.add(new String("test")); }
}
}
使用下面的命令运行该程序时设置JVM的堆内存(heap size)的极限值为10M(-Xmx10m)。
java -Xmx10m Test
很快,程序将会产生OOM的错误,如下图所示:

五、如何生成Head Dump文件?
我们可以在运行Java程序的时候,加入下面的参数:
-XX:+HeapDumpOnOutOfMemoryError
此参数是帮助生成dump文件,程序启动后直到抛出OOM异常。异常抛出后,在程序的classpath下会生成以一个以.hprof结尾的文件,如:java_pid4504.hprof,这就是我们需要的dump文件。
如下图所示:

六、使用IBM heapAnalyzer分析Head Dump文件
IBM heapAnalyzer(https://www.ibm.com/support/pages/ibm-heapanalyzer)是IBM开发的强大的内存dump分析工具,,IBM heapAnalyzer是通过分析OOM后的Java heap dump文件的,通过对dump文件的分析找到内存可能泄露的点。

启动IBM heapAnalyzer,并导入刚才生成的Heap Dump文件,如下图所示。

通过分析我们会发现,系统94.19%的内存都被一个ArrayList占用了(里面保存的都是Object)。这里就有可能是一个内存的溢出点。当然,我们这个例子非常典型,在实际工作可能没有这么明显,需要具体问题具体分析。

【赵渝强老师】如何分析Java的内存溢出问题的更多相关文章
- MAT工具定位分析Java堆内存泄漏问题方法
一.MAT概述与安装 MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题.该工具提供了两种使用方式,一种是插件版,可以安装到Eclips ...
- Java虚拟机内存溢出异常--《深入理解Java虚拟机》学习笔记及个人理解(三)
Java虚拟机内存溢出异常--<深入理解Java虚拟机>学习笔记及个人理解(三) 书上P39 1. 堆内存溢出 不断地创建对象, 而且保证创建的这些对象不会被回收即可(让GC Root可达 ...
- Java常见内存溢出异常分析(OutOfMemoryError)
原文转载自:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http:/ ...
- JVM:Java常见内存溢出异常分析
转载自:http://www.importnew.com/14604.html Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等,而Hotspot jvm的实现中,将堆 ...
- 性能分析 | Java服务器内存过高&CPU过高问题排查
一.内存过高 1.内存过高一般有两种情况:内存溢出和内存泄漏 (1)内存溢出:程序分配的内存超出物理机的内存大小,导致无法继续分配内存,出现OOM报错 (2)内存泄漏:不再使用的对象一直占据着内存不释 ...
- 【转】Java学习---内存溢出的排查经历
[原文]https://www.toutiao.com/i6595365358301872643/ 前言 OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空 ...
- java常见内存溢出(OOM)
jvm内存区域 程序计数器一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. java栈与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同.通常存放基本数据类型, ...
- 记一次java程序内存溢出问题
一个自然语言处理程序,在封装为web-service后,部署到线上运行. 但最近出现了内存溢出的情况,频繁的out of memory. 先盲目尝试在启动脚本中增加-XX:-UseGCOverhead ...
- 使用jvisualvm.exe工具查看java项目内存溢出(堆溢出)
在查看内存溢出的时候,我们需要明白,堆溢出和持久代溢出,他们不一样,说到内存泄漏,我们就需要明白,内存中 年老代和新生代,和持久代,这3块的数据 自己的理解: new了一个对象,会进入到堆里面,先放 ...
- java虚拟机内存溢出和泄漏实例
测试参数设置: 1.循环调用new A()实现堆溢出,java.lang.OutOfMemoryError: Java heap space, 虚拟机参数:-Xms1M -Xmx1M -XX:+Hea ...
随机推荐
- 🚀RabbitMQ+redis+Redisson分布式锁+seata实现订单服务
引言 订单服务涉及许多方面,分布式事务,分布式锁,例如订单超时未支付要取消订单,订单如何防止重复提交,如何防止超卖.这里都会使用到. 开启分布式事务可以保证跨多个服务的数据操作的一致性和完整性, 使用 ...
- CCF 有趣的数
问题描述: 试题编号: 201312-4 试题名称: 有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1 ...
- java面试一日一题:rabbitMQ如何保证消息不丢失
问题:请讲下rabbitMQ如何保证消息不丢失 分析:该问题属于概念题,同时也是一个设计方面的题,牵扯到部分设计层面的东西: 回答要点: 主要从以下几点去考虑, 1.rabbitMQ在保证消息不丢失方 ...
- 如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志)
如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志) SQL Server一直以来被人诟病的一个问题是缺少了像MySQL的慢日志功能,程序员和运维无法知道数据 ...
- 多智能体路径规划问题 —— Learn all about Multi-Agent Path Finding (MAPF)
地址: http://mapf.info/index.php/Main/Publications 与其对应的实验室地址: https://www.movingai.com/
- jax中对单步操作的缓存对性能造成的影响
代码: import jax.numpy as jnp from jax import grad, jit, vmap from jax import random def selu(x, alpha ...
- ubuntu22.04 终端显示数字剑雨
数字剑雨是读大学时候常用的屏保,这些年基本也再没有用过,不经意间想到了这个曾经的屏保,发现Ubuntu原版的桌面系统是没有屏保的,又不想换桌面系统,想想还是单独安装一下这个数字剑雨吧. 在Ubuntu ...
- 修复 Longhorn 卷挂载失败(”CentOS 7.6-'fsck' found errors on device“)
查看 Pod 日志 kubectl describe po clickhouse-0 -n clickhouse ...... #Events: # Type Reason Age From Mess ...
- 023.Ubuntu常见个性化配置
root登录设置 ubuntu默认关闭了root账户,可根据实际情况开启或关闭root登录. ubuntu@localhost:~$ sudo apt install openssh-server u ...
- springcloud线上发布超时之grpc
springcloud线上发布超时系列文章: springcloud线上发布超时之feign(ribbon饥饿加载) springcloud线上发布超时之grpc springcloud线上发布超时方 ...