JVM总结-OutOfMemoryError异常

在JVM规范中,除了程序计数器,虚拟机内存的其余几个运行区域都有可能发生OutOfMemoryError异常。java

Java堆溢出:

Java堆是用来存储对象实例,只要不停地建立对象实例,而且让GC ROOTS到对象之间有可达路径来避免垃圾回收机制清除这些对象,当对象数量达到最大堆的容量限制就会产生内存溢出的异常。框架

经过设置JVM参数-XX:+HeapDumpOnOutOfMemoryError能够让JVM在发生内存泄露异常Dump出当前内存堆转储快照方便后面分析。默认状况下,堆内存快照会保存在JVM的启动目录下名为java_pid<pid>.hprof 的文件里(在这里<pid>就是JVM进程的进程号)工具

当堆内存溢出时,会在异常信息后提示Java heap spacespa

使用内存映像分析工具进行分析,判断是内存溢出仍是内存泄露操作系统

一、内存泄露:3d

经过工具查看泄露对象到GC ROOTS引用链。就能够找到泄露对象是经过怎样的路径与GC ROOTS相关联,致使垃圾收集器没法自动回收他们对象

二、内存溢出:blog

检查虚拟机的堆参数,看是否还能够调大,从代码上检查某些对象生命周期过长,持有时间过长的状况。生命周期

例子:进程

使用JProfiler

一、打开快照文件

二、查看占用内存较大的对象

 

二、查看该对象经过怎样的路径与gc roots相关联

虚拟机栈和本地方法栈溢出

在HotSpot中是不区分虚拟机栈和本地方法栈的,虚拟机在扩展栈时没法分配到足够的内存空间就会抛出OutOfMemoryError。

方法区和运行时常量池溢出

运行时常量池溢出,错误后紧跟PermGen space说明运行时常量池属于方法区的一部分。

运行时产生大量的类可能填满方法区,如一些框架使用CGLib这类字节码技术,加强的类越多,就须要越大的方法区来保证动态生成的Class能够加载进内存

本机直接内存溢出

在Heap Dump中不会出现明显的异常,能够考虑是这个状况DirectByteBuffer直接经过反射获取Unsafe实例进行内存分配,会抛出内存溢出异常,可是他抛出的异常没有真正向操做系统申请分配内存,而是经过计算得知内存没法分配。

相关文章
相关标签/搜索