欢迎光临
我们一直在努力

JVM总结-OutOfMemoryError异常

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

Java堆溢出:

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

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

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

使用内存映像分析工具进行分析,判断是内存溢出还是内存泄露

1、内存泄露:

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

2、内存溢出:

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

例子:

使用JProfiler

1、打开快照文件

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

 

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

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

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

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

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

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

本机直接内存溢出

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

 

未经允许不得转载:ITyet » JVM总结-OutOfMemoryError异常

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
打开看板娘