JVM中的OOM异常(out of memory)

4 篇文章 0 订阅

A.可能抛出oom异常的内存:

    1.jvm运行时所管理的内存:除了程序计数器之外的内存(堆,方法区,虚拟机栈,本地方法栈)都有可能抛出oom异常。

            当然栈中有可能会抛出OOM异常也可能会抛出stack overflow Error。当请求的深度大于栈所允许的最大的深度,则抛出stack overflow error ,当栈的容量扩充,分配不到空间时抛出OOM.

    2.不属于jvm运行时管理的内存:Directory Memory (直接内存),NIO中,java对中有一个DirectoryByteBuffer引用指向直接内存,用户NIO操作,主要用来减少NIO内容在内存之间的复制。

 

B.抛出异常如何检查:

    1.内存泄漏(没用的对象,不能被回收) 

    2.内存溢出(对象都有用途,内存太小,在为对象申请空间时,分配(申请)不到足够内存。

C.调试方案:

    配置参数 -XX:+HeapDumpOnOutOfMemoryError  可以让虚拟机在出现内存溢出时,dump出转储快照,以便分析。

D.常见的OOM区域。

    1.java堆。Java堆是程序运行过程中常见的OOM区域,提示信息 java heap space

        解决方案:通过内存映像分析工具(Ecplise的Eclipse Memory Analyzer)对dump出来的快照进行分析。重点确认内存中的对象是否是必要的。如果是非必要的,那么属于内存泄漏,可以用工具查看对象到GC ROOTS之间的引用链(看看为啥导致了GC无法自动回收),找到内存泄漏的相应代码。如果不存在内存泄漏,那么有如下几种解决方案:a) 看看物理内存,确认虚拟机管理的堆内存是否还可以调大(-Xms 与-Xmx)。b)从代码检查,看看某些对象的生命周期是否过长,尝试减少程序运行过程中的内存消耗。

    2.虚拟机栈,本地方法栈。 (HotSpot虚拟机不区分这两个,直接直接设置栈容量即可-Xss)

        a) 单线程情况下,(减小栈内存、增大方法栈中的本地变量表长度)都抛出StackOverFlowError。

        b) 多线程情况下容易产生OOM异常,假如 JVM内存 一共 2G ,堆占了1G, 程序计数器内存占用很小,忽略。 那么1G的内存,分配给多个线程,每个线程分配到的内存越大,自然线程数就收到了限制。  如果需要更多的线程,自然会产生OOM异常。

        解决方案: qa)增大栈内存。qb)减小每个线程分配到的栈内存。

                    (个人见解)这两个解决方案看着有冲突(减小栈内存StackOverFlow,增加栈内存OOM),其实并不然。两者之间有一个平衡点。一般虚拟机默认的栈内存,不太容易抛出StackOverFlowError,因此在此基础上,我们需要的线程数量是可以控制或者说可以估量的,我们可以根据这个数量,计算出一个最小的栈内存,合理增大机器的内存即可。(当然如果极限情况,超出了寻址范围等,那么还是需要从两方面考虑。1.是否确实需要这么多线程  2.是否适当减小栈内存以增加线程数)。

    3.方法区和运行时常量池 (测试这个异常用String 的intern( ) 方法)   提示信息 PermGen space

            *JDK1.6及以前版本,运行时常量池都被分配在永久代里面,相当容易出现OOM异常。

            JDK1.7 及以后版本,方法区中主要出现OOM异常的原因不是运行时常量池,而是方法区中的Class相关信息(类名,访问修饰符,常亮,字段描述,方法描述)。因此在使用好多框架时,他们都会为我们生成代理对象(动态生成了Class),因此也是相当容易产生OOM异常。

        解决方案:查看一个类要被回收的条件(相当苛刻,专门描述一篇文章)。

    4.直接内存(DirectMemory)  直接内存默认和java堆内存大小一致。 可以使用-XX:MaxDirectMemorySize指定。

        如果是DirectMemory导致的内存溢出,溢出时,Dump的内存文件很小,没有明显异常,这个时候就应该考虑是DirectMemory抛出了OOM.

           解决方案:检查程序中是否使用到了NIO技术,因为NIO才会通过DirectByteBuffer对象直接在DirectMemory中分配内存。

              

        

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  1. 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

  2. 关注公众号 『逆行的碎石机』,不定期分享原创知识。

  3. 同时可以期待后续文章ing🚀

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值