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...”

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

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

      但是由于镜像连接不稳定性,我使用的是下载压缩包zip然后安装,压缩包下载地址为:http://ftp.jaist.ac.jp/pub/eclipse/mat/1.7/MemoryAnalyzer-1.7.0.201706130745.zip

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

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

  之后单击“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”中填写

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

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

  代码:

package com.study;

import java.util.ArrayList;
import java.util.List; public class TestStudy { static class OOMClass { } public static void main(String[] args) {
List<OOMClass> list = new ArrayList<OOMClass>();
while(true) {
list.add(new OOMClass());
}
} }

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

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

3.打开MAT的Perspective

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

  选择Memory Analysis并确定:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 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<OOMClass> list = new ArrayList<OOMClass>();
12 while(true) {
13 list.add(new OOMClass());
14 }
15 }
16
17 }

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

JVM内存溢出分析java.lang.OutOfMemoryError: Java heap space的更多相关文章

  1. eclipse:Tomcat设置jvm,解决java.lang.OutOfMemoryError: Java heap space 堆内存溢出

    eclipse 有启动参数里设置jvm大小,因为eclipse运行时自己也需要jvm,所以eclipse.ini里设置的jvm大小不是具体某个程序运行时所用jvm的大小,这和具体程序运行的jvm大小无 ...

  2. 解决eclipse maven install 造成JVM 内存溢出(java.lang.OutOfMemoryError: Java heap space)

    maven install 报错信息: The system is out of resources.Consult the following stack trace for details.jav ...

  3. 应用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap space)

    http://www.educity.cn/wenda/351088.html 使用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap s ...

  4. java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出

    上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...

  5. JMeter内存溢出:java.lang.OutOfMemoryError: Java heap space解决方法

    一.问题原因 用JMeter压测,有时候当模拟并发请求较大或者脚本运行时间较长时,JMeter会停止,报OOM(内存溢出)错误. 原因是JMeter是一个纯Java开发的工具,内存由java虚拟机JV ...

  6. eclipse内存溢出报错:java.lang.OutOfMemoryError:Java heap space

    今天执行了一个比較大的程序,处理的数据达到126MB数据,将数据导入数据库中,用eclipse 来訪问时候,总是出现java.lang.OutOfMemoryError:Java heap space ...

  7. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space(Java堆空间内存溢出)解决方法

    http://hi.baidu.com/619195553dream/blog/item/be9f12adc1b5a3e71f17a2e9.html问题描述Exception in thread &q ...

  8. Java堆空间溢出解决方法 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    一般通过java -jar filename.jar运行jar包,但是当运行的java程序需要较大的内存时,可能会造成堆空间溢出. 例如,加载了几个G大小的json文件,运行报错: Exception ...

  9. java.lang.OutOfMemoryError: Java heap space内存不足问题

    今晚,在定义一个new int[19001][13001]的数组时候内存不够:特转了一下方法: Exception in thread "main" java.lang.OutOf ...

随机推荐

  1. Spring框架的相关介绍

    Spring是一个开源轻量级的框架,它的核心是控制反转(IOC)和面向切面编程(AOP). 作为业务层框架的spring能够很好地整合表现层跟持久层. IOC:将类的创建和依赖关系写到配置文件里,可以 ...

  2. laravel项目本地数据库连接错乱原因和解决方法

    由于在本地建了两个laravel项目,test.me 和 api-test.me,当我在 test.me 中调用 curl 去请求 api-test.me 的方法,试图获取数据时, 接口一直返回没有找 ...

  3. .net 调用C++ dll

    .net C#调用C++ dll 主要分为以下的步骤 1.加载dll [DllImport("CallOtherLanguage.dll", EntryPoint = " ...

  4. python基础(32):进程(二)

    1. multiprocess模块 仔细说来,multiprocess不是一个模块而是python中一个操作.管理进程的包. 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含 ...

  5. SSM框架之Mybatis(1)入门

    Mybatis(1)入门 1.mybatis的概述 mybatis是一个持久层框架,用java编写的. 它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等 ...

  6. 高版本 MySQL 导出的脚本到低版本 MySQL 中执行时报错

    导入 MySQL 脚本时报错:[ERR] 1273 - Unknown collation: 'utf8mb4_0900_ai_ci'低版本还不支持 utfmb4 这个字符集 解决方法:将 sql 脚 ...

  7. DDoS攻击工具

    DDoS攻击工具 综合性工具 综合性工具除了可以进行DDoS攻击外,还可用于其他的用途,例如:端口扫描.安全审计.防火墙等.实际上,大部分综合性工具开发的原始目的并不是用于DDoS,而是"网 ...

  8. Xcode 7.3 解决自定义类无法自动联想

    正在苦拼的码友们,最近是不是觉得在写代码的时候很是头疼,甚至连个最基本的系统自带的语法啊.单词啊等等都不能联想了,之前习惯了的码友们,这个时候肯定会觉得是不是自己写错了,然后也往下翻了一大篇,还是找不 ...

  9. ucoreOS_lab4 实验报告

    所有的实验报告将会在 Github 同步更新,更多内容请移步至Github:https://github.com/AngelKitty/review_the_national_post-graduat ...

  10. [b0037] python 归纳 (二二)_多进程数据共享和同步_管道Pipe

    # -*- coding: utf-8 -*- """ 多进程数据共享 管道Pipe 逻辑: 2个进程,各自发送数据到管道,对方从管道中取到数据 总结: 1.只适合两个进 ...