前言:
  C/C++的程序员渴望Java的自由, Java程序员期许C/C++的约束. 其实那里都是围城, 外面的人想进来, 里面的人想出去.

背景:
  作为Java程序员, 除了享受垃圾回收机制带来的便利外, 还深受OOM(Out Of Memory)的困惑和折磨. 本文借鉴了<<深入理解 Java虚拟机>>, 并结合了小编自身的经历和读者一起面对OOM的困局如何分析和破解.

准备工作:
  工欲善其事必先利其器, 对java进程的快照分析, 是能够帮助我们迅速的定位出错的原因. 这边我们着重介绍内存分析相关的点.
  借助MAT(Memory Analyzer Tool)来分析内存快照.
  MAT的下载地址:
  http://www.eclipse.org/mat/downloads.php
  eclipse的插件url:
  http://download.eclipse.org/mat/1.4/update-site/
  MAT的展示效果如图所示:

内存快照:
  如何去触发java进程生成内存快照呢?
  1). 设定jvm参数, 使得进程在特定条件下进程内存dump.

-XX:+HeapDumpOnOutOfMemoryError	

  评注: 设置如下虚拟机参数后, 当java进程因为内存溢出, 就会自动对内存进行Dump, 以便相关人员事后进行分析/解读.
  该方案非常具有针对性, 在崩溃点分析往往能立马定位问题的所在. 该参数设定方案相当于飞机的黑盒子, 记录了出事前所有信息.
  当然该方案, 最大的局限性就是不能随时随地进行分析, 那如何破呢?
  2). JMap工具来生成
  JMap的使用命令描述:

Usage:
  jmap [option] <pid>
    (to connect to running process)
  jmap [option] <executable <core>
    (to connect to a core file)
  jmap [option] [server_id@]<remote server IP or hostname>
    (to connect to remote debug server) where <option> is one of:
  -dump:<dump-options> to dump java heap in hprof binary format
    dump-options:
    live dump only live objects; if not specified,
          all objects in the heap are dumped.
    format=b binary format
    file=<file> dump heap to <file>
  Example: jmap -dump:live,format=b,file=heap.bin <pid>

  评注: 挑选了部分选项说明, 重要的是dump的规则
  使用命令如下所示:

jmap -dump:format=b,file=xxx.hprof <pid> 

OOM的原因分类:
  导致程序出现OOM的因素有多种. 大致我们可以把OOM简单的分为堆溢出(Heap), 栈溢出(Stack), 永久代溢出(常量池/方法区), 直接内存溢出.
  先来看下java的内存分布
  1). 堆溢出(heap)
  编写如下例程:

public static void main(String[] args) {
  List<byte[]> datas = new ArrayList<byte[]>();
  while ( true ) {
    datas.add(new byte[1024 * 1024]);
  }
}

  同时设置虚拟机参数, 使得java进程能够快速生成heapdump.

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

  评注: 设置heap的内存限制在20m, Xms/Xmx分别对应heap的初始和最大heap大小.
  产生的异常信息:

  mat进行内存分析

  评注: 从这边能看出, 这边聚集了众多的对象, 占据了99%的内存量.
  2). 栈溢出(stack)
  栈溢出的异常, 还是具有明确的指向性的. 暂略.
  3). 永久代溢出(常量池/方法区)
  <<深入理解 Java虚拟机>>阐述了String.intern()和gclib产生动态代理类的两个例子.
  其错误也很有指向性:

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

  这边讲述下, 小编(mumuxinfei)很久之前做的一个项目.
  当时是机顶盒项目(采用IPanel浏览器, 相当于jvm虚拟机), 采用J2ME规范(java 1.1). 不过当时的机器性能不好, 内存少, 不像现在, 一些移动设备配置开始像PC靠齐了.
  我把一些初始化数据放在类里声明并定义时, 编译没问题, 但是jvm无论如何也run不起来, 总是出错. 不过我把这些数据放在文件里时, 通过运行时载入, 这样就没问题. 当时的我特别疑惑, 不都是内存吗? 同样的数据, 同样的内存, 这么差别就这么大呢?
  当时的我不理解, 后来知道java的内存结构, 我就明白了. 载入的数据放在Heap中, 而定义的常量是放在PermGen空间中. 而当初的设备限制, IPanel浏览器的默认永久空间大小比较小, 导致我只要把一些数据写到常量中定义, 就运行失败.
  不过蛮荒时代, 总是过去了, 现在的机器配置, 你是不会遇到这么诡异的事了. 日子在一天一天的变好, 过去苦难的日子, 现在的小年轻, 你是不会懂的...
  4). 直接内存溢出
  <<深入理解 Java虚拟机>>讲述了DriectByteBuffer的例子. 当然最直接, 也是最容易遇到的, 还是JNI的使用, 搞Android开发的大拿故意能遇到. 这边也略过不讲.

后记:
  从某种角度来说, <<深入理解 Java虚拟机>>已经把OOM的原因和例子说得非常具体了, 小编难以去超越它, 也不愿简单的复制罗列抄袭之. 简单的描述, 权当作学习笔记了.

Java 性能优化实战记录(3)--JVM OOM的分析和原因追查的更多相关文章

  1. Java 性能优化实战记录(2)---句柄泄漏和监控

    前言: Java不存在内存泄漏, 但存在过期引用以及资源泄漏. (个人看法, 请大牛指正) 这边对文件句柄泄漏的场景进行下模拟, 并对此做下简单的分析.如下代码为模拟一个服务进程, 忽略了句柄关闭, ...

  2. Java 性能优化实战记录(1)---定位并分析耗cpu最多的线程

    1) jps    列出相关的java进程, 以及对应的pid    也可以使用如下命令来尝试    ps aux | grep java --color 2) top -Hp <pid> ...

  3. JVM——九大工具助你玩转Java性能优化

    本文转载自 http://www.importnew.com/12324.html 本文由 ImportNew - 陈 晓舜 翻译自 idrsolutions.欢迎加入翻译小组.转载请参见文章末尾的要 ...

  4. 《Java性能优化权威指南》

    <Java性能优化权威指南> 基本信息 原书名:Java performance 原出版社: Addison-Wesley Professional 作者: (美)Charlie Hunt ...

  5. 推荐:Java性能优化系列集锦

    Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...

  6. Java性能优化,操作系统内核性能调优,JYM优化,Tomcat调优

    文章目录 Java性能优化 尽量在合适的场合使用单例 尽量避免随意使用静态变量 尽量避免过多过常地创建Java对象 尽量使用final修饰符 尽量使用局部变量 尽量处理好包装类型和基本类型两者的使用场 ...

  7. 我把阿里、腾讯、字节跳动、美团等Android性能优化实战整合成了一个PDF文档

    安卓开发大军浩浩荡荡,经过近十年的发展,Android技术优化日异月新,如今Android 11.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS. 但是,到了各大厂商手 ...

  8. Java 性能优化之 String 篇

    原文:http://www.ibm.com/developerworks/cn/java/j-lo-optmizestring/ Java 性能优化之 String 篇 String 方法用于文本分析 ...

  9. 读书笔记系列之java性能优化权威指南 一 第一章

    主题:java性能优化权威指南 pdf 版本:英文版 Java Performance Tuning 忽略:(0~24页)Performance+Acknowledge 1.Strategies, A ...

随机推荐

  1. 统计类别数量并且使用pyplot画出柱状图

    从数据库中读取数据,具体操作为: # -*- coding: utf-8 -*- from numpy import * import numpy as np import pandas as pd ...

  2. wScratchPad 实现刮刮卡效果

    插件网址http://wscratchpad.websanova.com/

  3. ubuntu连接Android调试

    从这周开始尝试Android开发,记下点滴. 安装JDK.下载ADT不说,连接手机调试的时候出错,一堆问号??????????.网上一查,属于典型错误.试下来,有几步比较关键,容易忽视: 1.我机器上 ...

  4. [Windows驱动]流媒体驱动开发

    从Windows98开始,Windows流媒体驱动遵循Windows Driver Model(WDM)模型并使用Kernel Streaming(KS)组件.Kernel Streaming(KS) ...

  5. D.T SOFTWARE (1) 软件架构直播答疑课程

    今晚的d.t课程 1项目需求 PPTP服务搭建完成PPTP服务器的搭建,用户重新拨号获得新IP后,要求拔PPTP VPN成功时,也获取到新的公网IP,而且能通过代理上网.VNC服务安装用户可以通过VN ...

  6. (转)Sencha Touch和jQuery Mobile的比较

    原文:http://extjs.org.cn/node/664 Sencha Touch和jQuery Mobile的比较 Posted 周三, 08/07/2013 - 10:07 by admin ...

  7. MAT

    http://www.yrom.net/blog/2014/08/29/eclipse-mat/

  8. Varnost slovenskih GSM omrežij III

    V torek smo pisali tudi o tem, da Si.Mobil v svojem omrežju dovoli uporabo A5/0 (nešifriranega preno ...

  9. BZOJ 2982 combination

    lucas定理裸题. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  10. R——启程——豆瓣影评分析

    专业统计的我,自然免不了学R的,今天仔细看了这篇教程(感谢学姐的推荐@喜欢算法的女青年),就学着用R仿照着做一个,作为R语言学习的起点吧. 影评数据是用python爬的,之后会在python爬虫系列补 ...