1)什么是OOM? 

OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError。看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是说,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。

2)为什么会OOM?

为什么会没有内存了呢?原因不外乎有两点:

1)分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。

2)应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。

内存泄露:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用。

内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出。

在之前没有垃圾自动回收的日子里,比如C语言和C++语言,我们必须亲自负责内存的申请与释放操作,如果申请了内存,用完后又忘记了释放,比如C++中的new了但是没有delete,那么就可能造成内存泄露。偶尔的内存泄露可能不会造成问题,而大量的内存泄露可能会导致内存溢出。

而在Java语言中,由于存在了垃圾自动回收机制,所以,我们一般不用去主动释放不用的对象所占的内存,也就是理论上来说,是不会存在“内存泄露”的。但是,如果编码不当,比如,将某个对象的引用放到了全局的Map中,虽然方法结束了,但是由于垃圾回收器会根据对象的引用情况来回收内存,导致该对象不能被及时的回收。如果该种情况出现次数多了,就会导致内存溢出,比如系统中经常使用的缓存机制。Java中的内存泄露,不同于C++中的忘了delete,往往是逻辑上的原因泄露。

3)OOM的类型

JVM内存模型:

按照JVM规范,JAVA虚拟机在运行时会管理以下的内存区域:

  • 程序计数器:当前线程执行的字节码的行号指示器,线程私有
  • JAVA虚拟机栈:Java方法执行的内存模型,每个Java方法的执行对应着一个栈帧的进栈和出栈的操作。
  • 本地方法栈:类似“ JAVA虚拟机栈 ”,但是为native方法的运行提供内存环境。
  • JAVA堆:对象内存分配的地方,内存垃圾回收的主要区域,所有线程共享。可分为新生代,老生代。
  • 方法区:用于存储已经被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。Hotspot中的“永久代”。
  • 运行时常量池:方法区的一部分,存储常量信息,如各种字面量、符号引用等。
  • 直接内存:并不是JVM运行时数据区的一部分, 可直接访问的内存, 比如NIO会用到这部分。

按照JVM规范,除了程序计数器不会抛出OOM外,其他各个内存区域都可能会抛出OOM。

最常见的OOM情况有以下三种:

  • java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。
  • java.lang.OutOfMemoryError: PermGen space ------>java永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize=64m -XX:MaxPermSize=256m的形式修改。另外,过多的常量尤其是字符串也会导致方法区溢出。
  • java.lang.StackOverflowError ------> 不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。

4)OOM分析--heapdump

要dump堆的内存镜像,可以采用如下两种方式:

  • 设置JVM参数-XX:+HeapDumpOnOutOfMemoryError,设定当发生OOM时自动dump出堆信息。不过该方法需要JDK5以上版本。
  • 使用JDK自带的jmap命令。"jmap -dump:format=b,file=heap.bin <pid>"   其中pid可以通过jps获取。

dump堆内存信息后,需要对dump出的文件进行分析,从而找到OOM的原因。常用的工具有:

  • mat: eclipse memory analyzer, 基于eclipse RCP的内存分析工具。详细信息参见:http://www.eclipse.org/mat/,推荐使用。
  • jhat:JDK自带的java heap analyze tool,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言OQL,分析相关的应用后,可以通过http://localhost:7000来访问分析结果。不推荐使用,因为在实际的排查过程中,一般是先在生产环境 dump出文件来,然后拉到自己的开发机器上分析,所以,不如采用高级的分析工具比如前面的mat来的高效。

这个链接:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html中提供了一个采用mat分析的例子 。

注意:因为JVM规范没有对dump出的文件的格式进行定义,所以不同的虚拟机产生的dump文件并不是一样的。在分析时,需要针对不同的虚拟机的输出采用不同的分析工具(当然,有的工具可以兼容多个虚拟机的格式)。IBM HeapAnalyzer也是分析heap的一个常用的工具。

什么是OOM,为什么会OOM及一些解决方法相关推荐

  1. Spark面对OOM问题的解决方法及优化总结 (转载)

    Spark面对OOM问题的解决方法及优化总结 (转载) 转载地址: http://blog.csdn.net/yhb315279058/article/details/51035631 Spark中的 ...

  2. Spark面对OOM问题的解决方法及优化总结

    转载请保持完整性并注明来源链接: http://blog.csdn.net/yhb315279058/article/details/51035631 Spark中的OOM问题不外乎以下两种情况 ma ...

  3. java oom_Java中关于OOM的场景及解决方法

    1.OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heap space 分  析 此OOM是由于JVM中heap的***值不满足需要,将设置 ...

  4. 导致溢出_1篇文章搞清楚8种JVM内存溢出(OOM)的原因和解决方法

    前言 撸Java的同学,多多少少会碰到内存溢出(OOM)的场景,但造成OOM的原因却是多种多样. 堆溢出 这种场景最为常见,报错信息: 原因 1.代码中可能存在大对象分配 2.可能存在内存泄露,导致在 ...

  5. 常见的 OOM 原因及其解决方法(OutOfMemoryError)

    当 JVM 内存严重不足时,就会抛出 java.lang.OutOfMemoryError 错误.本文总结了常见的 OOM 原因及其解决方法,如下图所示.如有遗漏或错误,欢迎补充指正. 1.Java ...

  6. idea内存溢出解决_各种OOM代码样例及解决方法

    针对目前大家对OOM的类型不太熟悉,那么来总结一下各种OOM出现的情况以及解决方法.把各种OOM的情况列出来,然后逐一进行代码编写复现和提供解决方法. 1. 堆溢出-java.lang.OutOfMe ...

  7. Android系统(134)--- Android关于OOM的解决方案 ##OOM

    Android关于OOM的解决方案 ##OOM 内存溢出(Out Of Memory) 也就是说内存占有量超过了VM所分配的最大 ##出现OOM的原因 加载对象过大 相应资源过多,来不及释放 ##如何 ...

  8. FakeAPP训练时错误【ResourceExhaustedError: OOM】解决方法

    背景 在使用FakeApp训练的时候出错,表现为点击"train"按钮后一段时间就报错,且没有训练预览窗口弹出. log文件里显示 undefinedUsing GPU0 for ...

  9. JVM 各种OOM问题与解决方法

    转自:http://zhaohe162.blog.163.com/blog/static/38216797201110232341953/ 1.OOM for Heap=>例如:java.lan ...

  10. 各种OOM代码样例及解决方法

    点击上方「蓝字」关注我们 针对目前大家对OOM的类型不太熟悉,那么来总结一下各种OOM出现的情况以及解决方法.把各种OOM的情况列出来,然后逐一进行代码编写复现和提供解决方法. 1. 堆溢出-java ...

最新文章

  1. 花了几百万,创业一年学到了什么
  2. python字典append_python中字典重复赋值,append到list中引发的异常
  3. 手写 Promise
  4. 元宵节电商促销活动首页PSD分层模板
  5. 阅读一定时间后获得实现逻辑_大家都在好奇,18天读18本书的60分钟高效阅读,怎么这么火...
  6. 华为鸿蒙系统手机匹配,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可 !【手机吧】_百度贴吧...
  7. Spring配置中的classpath:与classpath*:的区别研究(转)
  8. XNA 三维入门讲解
  9. 身份证丢失后信息安全亟需上锁
  10. 【图像去雾】基于matlab偏振水下模糊图像去雾【含Matlab源码 396期】
  11. 独立成分分析(Indenpendent Components Analysis)斯坦福公开课讲义
  12. OFD文件如何打印?怎么打开?如何转换PDF?
  13. 艾肯4nano声卡调试教程,效果演示
  14. 通过keil5下载hex文件
  15. 用chrome 观看youtube视频显示中文字幕
  16. CHAP7 软件项目进度计划
  17. vue3+ts实现todolist功能
  18. 怎样用计算机放音乐,QQ音乐怎么用手机控制电脑放歌曲,qq音乐怎么连接电脑|qq音乐怎么用手机控制电脑...
  19. 简述JS中 appy 和 call 的详细用法
  20. IDEA入门教程----是时候舍弃Eclipse了

热门文章

  1. 来学习开发一个网页版马里奥小游戏吧
  2. 后端进阶,要搞懂哪几块?
  3. 面试:一个Java字符串到底有多少个字符?
  4. 忘掉什么鬼并发,先听完这个故事!
  5. 微软宣布加入 OpenJDK,打不过就改变 Java 未来!
  6. flink 三种时间机制_360深度实践:Flink 与 Storm 协议级对比
  7. 【redis】redis持久化
  8. yolov5组件笔记
  9. 提升注意力模块性能dcanet
  10. 相邻帧差法和三帧差法