Java中的OOM问题
OOM是什么
OOM全称"OutOfMemory",既内存溢出。我们知道,Java中的对象是在堆(heap)上创建的,当堆内存不足以为新创建的对象分配空间时,就会产生OutOfMemoryError。
为什么会产生OOM
由于GC机制的存在,Java程序员不需要过多地关注内存的分配与回收,GC通过“可达性分析”来判断一个对象是否需要被回收。
可达性分析:GC首先确定一组GC Root节点(通常是一些全局性的元素,例如JVM持有的对象),然后根据GC Root是否持有指向某个对象的引用或引用链来判断这个对象是否“可达”。
GC会回收大部分的无用对象,当发生OOM时,通常会有两种情况:
- JVM的堆内存真的不足了
- 代码问题
如果是堆内存不足,只需要简单地扩大堆内存就可以了。但是绝大多数情况下,OOM都是由代码问题引发的,也就是说很多本该被回收的对象没有被回收,导致堆内存不足。
如何处理OOM问题
处理OOM问题的关键在于拿到Heap Dump(堆转储文件),它保存了某一时刻JVM堆中对象对内存的使用情况。获取Heap Dump文件可以通过:
- 启动程序前,添加JVM参数
-XX:+HeapDumpOnOutOfMemoryError
该参数的含义是:当发生OOM时,生成Heap Dump文件。
- 程序运行过程中, 通过jmap获取。首先通过jps获取到Java进程的pid,然后通过jmap输出Dump文件
jmap -dump:live,format=b,file=<filepath> <pid>
其中filepath是生成dump文件的位置,pid是你想要分析的Java进程的pid。
拿到dump文件后,就可以通过一些图形化工具来进行分析了。常用的图形化工具有visual VM、MAT、JProfiler等。
举个栗子
- 首先我们编写一个程序,并设置JVM最大堆内存为128M,使其在一段时间后发生OOM,并使用vitual VM进行简单的分析。
-Xmx128m
import java.util.ArrayList;
import java.util.List;
public class OOMExample {
public static void main(String[] args) throws InterruptedException {
List<byte[]> list = new ArrayList<>();
for(int i=0;i<128;i++){
list.add(new byte[1024*1024]);
Thread.sleep(500);
}
}
}
- 运行期间我们通过在命令行中输入jps可以获取到当前进程pid。也可以通过vitual VM直接查看(我这里是分开两次运行截的图所以pid不一致)。


- 通过vitual VM我们可以看到程序的实时运行情况,正常情况下程序的内存曲线应该是波浪形,我们的程序即将发生OOM。

- 通过jmap获取dump文件
jmap -dump:live,format=b,file="/12844.hprof" 12844
- 使用vitual VM查看dump文件

很明显可以看到byte数组占据了绝大部分的内存,这与我们的预想一致。实际场景中,OOM的对象引用关系要比这复杂得多,具体问题具体分析,如何快速发现问题代码,也是一个难题,本文权当抛砖引玉。
Java中的OOM问题的更多相关文章
- Java中关于OOM的场景及解决方法
原文地址:http://developer.51cto.com/art/201112/305696.htm 1.OOM for Heap=>例如:java.lang.OutOfMemoryErr ...
- Java中关于OOM的场景及解决方法(转)
http://developer.51cto.com/art/201112/305696.htm 1.OOM for Heap=>例如:java.lang.OutOfMemoryError: J ...
- [转载] java中关于OOM的场景及解决方法
1.OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heapspace[分析] 此OOM是由于JVM中heap的最大值不满足需要,将设置hea ...
- java中OOM错误解析(面试可以聊的东西)
嗯,生活加油鸭.... 实习中遇到OOM错误 GC overhead limit exceeded 问题,所以整理一下OOM异常问题: 先看一下“阿里的开发手册”对OOM的描述: OOM,全称“Out ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- Java中的字符串常量池
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...
- 理论篇-Java中一些零碎的知识点
1. Java中length,length方法,size方法区别 length属性:用于获取数组长度. length方法:用于获取字符串长度. size方法:用于获取泛型集合有多少个元素. 2. is ...
- java中引用的概念
强引用(StrongReference) 强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用: 1 2 Object object = new Object(); ...
- JAVA中的引用
关于值类型和引用类型的话题,C++.JAVA.python.go.C#等等高级语言都有相关的概念,只要理解了其底层工作原理,可以说即使是不同的语言,在面试学习工作实践中都可以信手拈来(不要太纠集语言) ...
随机推荐
- python使用matplotlib:subplot绘制多个子图 不规则画图
https://www.cnblogs.com/xiaoboge/p/9683056.html
- 使用Python中的NLTK和spaCy删除停用词与文本标准化
概述 了解如何在Python中删除停用词与文本标准化,这些是自然语言处理的基本技术 探索不同的方法来删除停用词,以及讨论文本标准化技术,如词干化(stemming)和词形还原(lemmatizatio ...
- CDN 内容分发
1,传统架构访问服务器资源: www.aiyuesheng.com/page/logo.png 这是部署在服务器上的一张图片,因为服务器部署在上海,所以在上海或周边的人访问要稍微快一点,但是,若是云南 ...
- JS烟花案例优化版
不明白为什么是烟花优化版本的先参考作者的烟花基础版本 烟花优化版本主要实在优化爆炸的范围和运动上做了优化,爆炸范围我们采用已圆的爆炸方式,以鼠标点击的位置为圆形爆炸的烟花效果 <!DOCTYPE ...
- 使用 nodejs 对文件进行批量重命名
0. 前言 从B站下载了一点视频,硕鼠自动将标题添加到了每个文件名的前面,导致文件名过长,不方面查看文件的具体内容. 虽然只有二十几个文件,但是手动删除前缀还是个不小的工作量,还有可能删除错误.考虑到 ...
- 8.MSFvenom
Meterpreter 01 Meterpreter API调用 Meterpreter提供了多种APl调用,在编写自己的脚本时可以使用这些API来提供额外功能或定制功能. 关于ruby的更多信息,请 ...
- MFC 工具栏ToolBar
一.创建工具栏 1.在MFC工程,找到“资源视图”界面,右键添加资源,选择Toolbar,点击新建: 2.修改工具条属性: 3.添加工具: 新建ToolBar后,会自动生成一个工具,编辑ID后,工具条 ...
- 1054 The Dominant Color (20分)(水)
Behind the scenes in the computer's memory, color is always talked about as a series of 24 bits of i ...
- VBScript - 弹出“文件选择对话框”方法大全!
本文记录,VBScript 中,各种打开 "文件选择对话框" 的方法. 实现方法-1 (mshta.exe): 首先,我们要实现的就是,弹出上面的这个"文件选择对话框&q ...
- JVM 理解性学习(一)
重新学习,重新理解 1.类加载过程等 验证:.class 文件加载到 JVM 里的时候,会验证下该文件是否符合 JVM 规范. 准备:给实体类分配内存空间,以及给类变量(static 修饰)分配&qu ...