memory java heap_JVM内存溢出分析java.lang.OutOfMemoryError: Java heap space

JVM内存溢出查询java.lang.OutOfMemoryError: Java heap space查出具体原因分为几个预备步骤

1、在运行java程序是必须设置jvm

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump_OOME.hprof   当内存溢出时 会输出在/tmp/dump_OOME.hprof目录下

#jvm options

#JAVA_OPTS="-Xms8192m -Xmx8192m -Xmn4096m -Djava.awt.headless=true -XX:MaxPermSize=512m -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+DisableExplicitGC -Xnoclassgc -Xverify:none"JAVA_OPTS="-Xms4096m -Xmx4096m -Djava.awt.headless=true -XX:MaxPermSize=512m -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+DisableExplicitGC -Xnoclassgc -Xverify:none"JAVA_OPTS="$JAVA_OPTS -javaagent:/usr/local/src/sflowagent.jar -Dsflow.hostname=platform -Dsflow.dsindex=10000"JAVA_OPTS="$JAVA_OPTS -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/tmp/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M"JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump_OOME.hprof"

2、可以在eclipse安装分析dump_OOME.hprof 的插件MemoryAnalyzerTool

MemoryAnalyzerTool(也叫MAT)是一款JAVA虚拟机内存映像分析工具,

可以在JAVA程序运行的时候有程序抛出的异常加上已经设置好的参数(-XX:+HeapDumpOnOutOfMemory)调试出内存泄漏或者异常的位置以及原因跟踪,

MemeoryAnalyzer可以对Dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要先确认到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory OverFlow)。

运行Eclipse,然后单击菜单栏上“Help=》Install New Software...”

f971d85f67757eba82b5047be96578b8.png

进入软件源导入界面,你可以选择使用URL直接导入,URL导入的地址为:

http://download.eclipse.org/mat/1.7/update-site/

下载完成之后将其导入,"Add》Archive》选择你下载好的zip文件》OK":

425380cb0ae768a87bc3383d3c19c3ee.png

确定之后勾选"Memory Analyzer for Eclipse IDE"下面的两项即可,这个是用于Eclipse内部使用的插件,下面一个“Stand-alone Memory Analyzer“是独立的分析工具,一般不用勾选。

e8863157a4d31fafeb2963ec82d18a10.png

之后单击“Next"等待一段时间Eclipse计算的需求和依赖文件下载完毕后,一路"next",并接受协议“Finish”即可完成安装,重启Eclispe后就可以使用MAT了。

3、使用Memory Analyzer 分析内存溢出

1.设置JVM参数

JVM的参数可以用于调试JVM在各种限制条件下的常见BUG,一下简单介绍几个参数:

-XX:+HeapDumpOnOutOfMemoryError //虚拟机在堆异常时生成对存储快照,后缀一般是.hprof

-Xms //Java堆的最小值,例如-Xms20m,将Java堆的最小值设置为20MB

-Xmx //Java堆的最大值,例如-Xms40m,将Java堆的最大值设置为40MB

了解了参数之后,可以对参数进行一定的设置,以便我们简单的对MAT工具进行使用测试,设置参数如下:

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=D://dump_OOME.hprof

-Xms20m

-Xmx20m

之所以将最小和最大的堆设置为一样是为了能避免堆的自动扩展,以及20MB的空间是为了让程序能尽快的占满使得内存溢出。

设置JVM的启动参数可在“Run》Run Configuration》Arguments》Vm arguments”中填写

04d191c978f14d04b55623e11ab93bf8.png

2.编写内存溢出(Memory Leak)代码

思路:通过新建集合列表List,然后以while(true)死循环的方式使得List集合不断添加新的对象,使得其不断地占满堆空间

代码:

48304ba5e6f9fe08f3fa1abda7d326ab.png

package com.study;

import java.util.ArrayList;

import java.util.List;

public class TestStudy {

static class OOMClass { }

public static void main(String[] args) {

List list = new ArrayList();

while(true) {

list.add(new OOMClass());

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

执行代码,发现输出如下:

37138af7aede142035e413f294134f4e.png

注意到“java_pid24792.hprof”文件,这个文件是JVM生成的对存储快照,之后可以通过MAT工具打开,进行分析追踪,这个文件将自动保存到你的Eclipse workspace下的工作目录中,以我的为例:

85fbce69e093a4522e05affa0f15f9c4.png

3.打开MAT的Perspective

由于MAT工具需要另外打开一个工作视图(就像Eclipse EE和Java的切换视图一样),因此需要在先配置打开"Window》Perspective》Open Perspective》Other...":

a8085fd6322f517b652c5afdc0b3a884.png

选择Memory Analysis并确定:

9d68319e2474970527d923abbef1a313.png

完后之后将进入MAT的工作空间视图,你可以在Eclipse右上角进行切换回Java或者EE,由于接下来要使用MAT分析,因此就暂时不切回之前的Java了

5ccc8703a4e212aaa715523f68349800.png

4.打开需要分析的堆转储快照.hprof文件

由于MAT是依赖于生成的堆转储快照,而不是在运行的时候自动捕获,因此,再确认进入MAT的工作空间后,点击"File》Open Heap Dump》选择刚生成的“java_pid24792.hprof”文件,一直默认就可以查看内存问题的分析图表以及GC根

bcbd1646a078d63cc963e1d4e47c4ea9.png

你可以进行一些分析操作,可以看到Action下的几个选项:

a.Histogram:列出每个类的实例列表;

b.Dominator:列出最大的对象和他们存在的东西;

c.Top Comsumer:打印按类和包分组的最昂贵的对象;

d.Duplicate Classes:检测由多个类加载器加载的类。

5.使用MAT找出问题存在的对象

由于是一个简单的问题,因此我们直接选择Dominator,可以直接以百分比的形式打印出对象所占的百分比,一般的内存溢出大部分情况都是有某一个对象过多存在而未被GC回收导致,所以可以点开最大百分比的类一级级找,不难找到问题所在:

f2f20aab1ce3d9e420c03ce5129fcef0.png

可以看到列出额其中的25条,还有810300条目未列出,这81万个对象占据了97.36%的堆空间,因此不难发现是OOMClass类的对象生成过多为未被回收导致内存溢出。

6.进一步追踪问题源并进行定位

在"default_report org.eclipse.mat.api:suspects"的标签分页中

be849842ee255579bda0f66083797c73.png

在"Program Suspect 1》Details"点击后找到"Thread Stack"中追踪出错点

c73d6e66ccd16ad46b936d3ac3df5b2c.png

看到出错点在第13行,找到对应的Java代码TestStudy的13行:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 package com.study;

2

3 import java.util.ArrayList;

4 import java.util.List;

5

6 public class TestStudy {

7

8 static class OOMClass { }

9

10 public static void main(String[] args) {

11 List list = new ArrayList();

12 while(true) {

13 list.add(new OOMClass());

14 }

15 }

16

17 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

找到了追踪的出错位置,以上就是使用Memory Analyzer工具完成的堆栈分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值