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、内存溢出:

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

例子:

0e671257d14f3c61b24cc48487d29d74e66.jpg

使用JProfiler

1、打开快照文件

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

a8b57420fc204deca6f0d6c6e2f26f0ae6d.jpg

 

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

21bdb7f9221cefec1ae1c8ce069928edf31.jpg

6216ad7820c0fc0af594ae16908389a8c85.jpg

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

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

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

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

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

本机直接内存溢出

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

 

转载于:https://my.oschina.net/u/4108677/blog/3034006

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值