这篇帖子只介绍利用MemoryAnalyzer进行简单的JVM的堆的分析,至于JVM的内部结构是怎么样的,这里不进行分析。好吧,废话不多说;首先如果我们要分析JVM某个时刻的Heap的对象分配情况,我们就必须要dump这个时刻的JVM的heap(堆);有以下几个办法进行dump某个时刻JVM的heap内容:

1、 使用$JAVA_HOME/bin/jmap -dump来触发, 

                eg:jmap-dump:format=b,file=/home/longhao/heamdump.out <pid>

         2、 使用$JAVA_HOME/bin/jcosole中的MBean,到MBean>com.sun.management>HotSpotDiagnostic>操作>dumpHeap中,点击 dumpHeap按钮。生成的dump文件在   java应用的根目录下面。

         3、在应用启动时配置相关的参数 -XX:+HeapDumpOnOutOfMemoryError,当应用抛出OutOfMemoryError时生成dump文件。

         4、使用hprof。启动虚拟机加入-Xrunhprof:head=site,会生成java.hprof.txt文件。该配置会导致jvm运行非常的慢,不适合生产环境。

利用MemoryAnalyzer进行Heap分析

        去eclipse官网上去下载MemoryAnalyzer,可以下载非插件版的,这样MemoryAnalyzer运行起来比较快,如果是eclipse插件版进行可能会导致eclipse卡死。本人下载的版本是MemoryAnalyzer-1.2.0.20120530-win32.win32.x86_64。

一、Java代码样例

[java] view plaincopy

  1. package org.ph.javaee.javaheap;
  2. import java.util.Map;
  3. import java.util.HashMap;
  4. /**
  5. * JVMOutOfMemoryErrorSimulator
  6. *
  7. * @author PH
  8. *
  9. */
  10. public class JVMOutOfMemoryErrorSimulator {
  11. private final static int NB_ITERATIONS = 500000;
  12. // ~1 KB data footprint
  13. private final static String LEAKING_DATA_PREFIX = "datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata";
  14. // Map used to stored our leaking String instances
  15. private static Map<String, String> leakingMap;
  16. static {
  17. leakingMap = new HashMap<String, String>();
  18. }
  19. public static void main(String[] args) {
  20. System.out.println("JVM OutOfMemoryError Simulator 1.0");
  21. System.out.println("Author: Pierre-Hugues Charbonneau");
  22. System.out.println("http://javaeesupportpatterns.blogspot.com/");
  23. try {
  24. for (int i = 0; i < NB_ITERATIONS; i++) {
  25. String data = LEAKING_DATA_PREFIX + i;
  26. // Add data to our leaking Map data structure...
  27. leakingMap.put(data, data);
  28. }
  29. } catch (Throwable any) {
  30. if (any instanceof java.lang.OutOfMemoryError) {
  31. System.out.println("OutOfMemoryError triggered! "
  32. + any.getMessage() + " [" + any + "]");
  33. } else {
  34. System.out.println("Unexpected Exception! " + any.getMessage()
  35. + " [" + any + "]");
  36. }
  37. }
  38. System.out.println("simulator done!");
  39. }
  40. }

二、设置JVM启动参数

         在此我们把JVM堆的最大内存设置为512m,并且让程序运行过程中出现内存溢出的时候会dump当时的JVM对内存的内容,所以需要加上XX:+HeapDumpOnOutOfMemoryError参数;因此按照以下步骤在eclipse中加入启动参数

三、运行程序

        运行程序,然后观察控制台的输出,输出结果如下:

从以上的输出结果来看,此程序已经抛出了OutOfMemoryError了,并且生成了一个heap文件,文件名为java_pid3880.hprof,下一步我们就可以拿这个文件在MemoryAnalyzer分析了。

四、导入heap文件分析

导入后按照以下步骤执行进行内存泄露的可疑分析;

鼠标点击红色的部分会出现菜单,选中菜单的第一行的List objects > With Incoming references,就会出现以下界面

此图展现了HashMap$Entry被引用的路径,HashMap$Entry被一个java.util.HashMap的table实例变量引用,而这个HashMap又被JVMOutOfMemberyErrorSimulator类变量leakingMap引用,所以通过这些路径就很容易找到是哪段代码导致的内存溢出。

        通过以上分析我们就发现,类JVMOutOfMemberyErrorSimulator的leakingMap变量的内容太大导致了内存溢出,所以这样就能很快定位到问题。

        其中注意Shallow vs. Retained Heap的区别,这里不进行解释,点击MemoryAnalyzer的Help菜单里面的HelpContents就可以查找到

        这里解释下Java Local,JVM里面的类变量,实例变量的名字在JVM里面都有记录,而局部变量是没有记录的,所以Java Local在这里就代表局部变量。

总结:以上的这些分析方法是入门级别的,现实中的OOM分析肯定比这更复杂,本人就曾经遇到过很多诡异的OOM。但在一般情况下,如果出现OOM,那么我们肯定需要对JVM的heap进行分析,这篇帖子是一个很好的思维方法;当然你也可以利用其他的工具进行heap分析,但思路大概都差不多;MemoryAnalyzer是一个不错的工具,里面有很多的小工具给我分析,可以花点时间看看。

利用MemoryAnalyzer进行OutOfMemoryError的诊断分析的更多相关文章

  1. 利用 SysRq 键排除和诊断系统故障

    说白了,SysRq手动触发而不用命令, /proc/sysrq-trigger 这个是通过命令接口 实验:LINUX窗口下 ,CTRL+ALT+F1,切换到TTY1,在文本模式下,按下 ALT+Sys ...

  2. 如何更好地利用Pmd、Findbugs和CheckStyle分析结果

    这里列出了很多Java静态分析工具,每一种工具关注一个特定的能发挥自己特长的领域,我们可以列举一下: Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可能的bug— ...

  3. 利用WebBrowser实现Web打印的分析

    原文:利用WebBrowser实现Web打印的分析 WebBrowser是IE内置的浏览器控件,无需用户下载.本文档所讨论的是有关IE6.0版本的WebBrowser控件技术内容.其他版本的IE应该也 ...

  4. gops —— Go 程序诊断分析工具

    GitHub: https://github.com/google/gops 一个用于列出和诊断分析系统中正在运行的 Go 程序的命令行工具 安装 go get -u github.com/googl ...

  5. 如何利用Flink实现超大规模用户行为分析

    如何利用Flink实现超大规模用户行为分析   各位晚上好,首先感谢大家参与我的这次主题分享,同时也感谢 InfoQ AI 前线组织这次瀚思科技主题月! 瀚思科技成立于 2014 年,按行业划分我们是 ...

  6. 如何利用wireshark对TCP消息进行分析

    原文:https://www.cnblogs.com/studyofadeerlet/p/7485298.html 如何利用wireshark对TCP消息进行分析   (1) 几个概念介绍 1 seq ...

  7. cognos服务器性能测试诊断分析优化过程记录

    前段时间客户方一个系统上线后出现性能问题,就是查询报表的时候出现宕机现象,应项目组要求过去帮忙测试优化问题.  该项目的架构相对比较复杂,登录后要先进行认证服务器认证用户然后登录到应用系统A,在跳转到 ...

  8. mysql查询诊断分析工具

    Query Profiler是MYSQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方.通常我们是使用的explain,以及slow query log都无法做到 ...

  9. Python中利用LSTM模型进行时间序列预测分析

    时间序列模型 时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征.这是一类相对比较复杂的预测建模问题,和回归分析模型的预测不同,时间序列模型是依赖于事件发生的先后顺 ...

随机推荐

  1. codefroce385E矩阵快速幂

    状态变化  (x,y,dx,dy,i) 表示i时刻熊站在(x,y)处速度向量(dx,dy)下一个状态是 ( 2x+y+dx+i , x+2y+dy+i , x+y+dx , x+y+dy , i+1 ...

  2. Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)

    --20170322 --1.0 --更新表的统计信息begin dbms_stats.set_table_stats(user,'EMP',numrows => 10000);end; beg ...

  3. echarta3 北京,上海地图

    1.首先你得到echarts官网下载js,建议下载完整代码,这样你就很容易根据我的路径找到beijing.js 2.把echarts.js和beijingi.js根据你的路径引对,然后就可以copy我 ...

  4. mysql迁移oracle

    有很多应用项目, 刚起步的时候用MYSQL数据库基本上能实现各种功能需求,随着应用用户的增多,数据量的增加,MYSQL渐渐地出现不堪重负的情况:连接很慢甚至宕机,于是就有把数据从MYSQL迁到Orac ...

  5. hdu1512

    题解: 每一次合并两个对 修改操作就和普通的堆一样 代码: #include<cstring> #include<cmath> #include<cstdio> # ...

  6. 在ASP.NET中将GridView数据导出到Word、Excel

    在ASP.NET中将GridView数据导出到Word.Excel asp.net,导出gridview数据到Word,Excel,PDF   #region Export to Word, Exce ...

  7. NameError: name 'picamera' is not defined

    /********************************************************************************* * NameError: name ...

  8. multiprocessing创建自定义进程类

    1.继承Process2.编写自己的__init__,同时加载父类init方法3.重写run方法,可以通过生成的对象调用start自动运行 from multiprocessing import Pr ...

  9. Linux内核调试

    1.控制台优先级配置cat /proc/sys/kernel/printk6 4 1 76是控制台的优先级,打印信息的优先级要比它高才能打印出.4是默认的优先级cat /var/log/message ...

  10. C# winform javascript 互调用

    1.准备环境 vs2010 2. 项目结构 index.htm 为需要显示的web页面 其中需要操作提供的方式的C# 调用的javascript 方法 以及进行测试javascript 调用C# 方法 ...