oom:out of memory error
什么叫oom
oom是指没有足够的内存分配给想要使用内存的对象。oom分类
java堆溢出
堆中存放的对象是对象实例,只要不断的创造对象并且保证对象没有被回收(gc roots可达),这样就能不断的使用堆中的内存,导致堆中空间不够,产生oom栈溢出
java栈分为两种:虚拟机栈,本地方法栈栈中可能有两种异常
stack overflow error:线程请求的深度大于栈的最大深度
out of memory error:栈拓展空间是获取不到足够的空间
* 栈中存放的是函数执行相关的(局部变量,函数地址,函数参数),想要人为的实现栈溢出的,就需要不停的执行方法。
虚拟机栈
虚拟机栈中存放的是Java方法执行的内存模型,每个Java方法的执行对应着一个栈帧的进栈和出栈的操作本地方法栈
本地方法栈中存放的是类似“JAVA虚拟机栈”,但是为native方法的运行提供内存环境。方法区和运行时常量池
运行时常量池就在方法区中,方法区中存放的是class的相关信息,如类名,访问修饰符,常量池,字段描述。如果想要方法区溢出,要产生大量的class占满方法区,可以利用反射机制。来自远方的补充
OutOfMemoryError异常
Java堆溢出
- 是常见的内存溢出异常情况
- 解决异常的方法
- 通过内存映像分析工具对Dump出来的堆转储快照进行分析
- 主要是确定时出现了内存泄漏还是内存溢出
内存泄漏
- 查看泄漏对象到GC Roots的引用链。找到泄漏对象时通过怎样的路径与 GC Roots相关联并导致垃圾收集器无法自动回收他们的。
- 掌握了泄漏对象的类型信息及GC Roots引用链的信息,就可以比较准确定位出泄漏代码的位置。
内存溢出
- 内存的对象确实还存活着
- 检查虚拟机的堆参数,与机器物理内存对比看是否可以调大。
- 代码上,检查某些对象生命周期过长、持有状态实践过长的情况,尝试减少程序运行期的内存消耗。
虚拟机栈和本地方法栈溢出
- 如果线程请求的栈深度大于虚拟机所允许的最大深度,则抛出StackOverflowErroe异常
- 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutMemoryError异常
- 对一个问题的两种描述
- 如果时建立过多线程导致的内存溢出,在不能减少线程数或者更换64为虚拟机的情况下,就只能通过减少最大堆和减少栈容量和换取更多的线程。
方法区和运行时常量池溢出
- 方法区用来存放class的相关信息,如类名、访问修饰符、常量池等。
- 方法区溢出也是常见的内存溢出异常
- 一个类要被垃圾收集器回收掉,判定条件时比较苛刻的。
本机直接内存溢出
- 如果不指定,大小默认与Java堆最大值一样。
- 在Heap Dump文件中不会看到明显的异常
《java虚拟机》
java内存模型
oom