JVM学习和分析(三):OOM

一、关于OOM

  对于JAVA程序员来说,恐怕都到过OOM这个可怕的梦厣,写出一段经常出现OOM的代码,恐怕也是对于一个程序员最大的耻辱。OOM出现的原因多种多样,在我刚开始写程序的时候,天真的以为OOM真的只是内存不够了,后来才发现,那个时候真的很傻很天真

 

二、诱发OOM的原因

  OOM的原因基本上是因为在JVM做过一次GC(可能是YGC也可能是FULL GC)后,仍有大量对象存活,导致内存在无法释放的前提下,不断的有新的对象产生,最终导致某一块区域的内存不够,从而抛出OOM

 

三、各种OOM

  1、堆溢出

   由堆溢出引发的OOM是最常见的一种,这种OOM多半是由于程序员在写代码时,对内存的乱用导致的

   导致堆溢出的原因一般有两个:内存泄漏、内存溢出

     内存泄漏:需要通过一些工具确定是哪部分内存泄漏,修复之即可解决

     内存溢出:由于内存中的对象必须存活,而导致的内存不足,一般这类问题通过调整-Xmx和-Xms可以得到解决

   异常中的相关提示:Java heap space

   个人经验:

     减少对象存活时间:尽量避免让对象进入S0,01和OLD区,在Eden区的对象都是可以被快速回收的,从而释放内存

     减少对象数量:一个线程中尽量避免有大对象列表或是MAP,从而减少每个线程占用的内存空间

 

  2、本地方法栈溢出

   本方方法栈会有两个异常抛出:OutOfMemoryException和StackOverflowException

   OutOfMemoryException:

     JVM扩展内存时,无法申请到足够的内存,通过在多线程环境下会出现这种问题

     原因:

       JVM每创建一个线程就会为线程创建一份本地方法栈内存,当线程过多时,会导致内存不足

     解决办法:

       a、减少线程数量,使每个线程可以得到更多的内存

       b、通过设置-Xss减少栈内存容量,使JVM可以创建更多的线程

   StackOverflowException:

     线程请求的栈深度超出JVM允许的最大深度

   个人经验:

     减少本地变量定义

     可分配给栈使用的内存=每个进程可使用的最大内存(系统限制)-Xmx-MaxPermSize-JVM进程占用内存

 

  3、方法区溢出

   由于创建了大量的类,方法区内存被完全使用,无法再存储新对象实例的相关信息(类名,访问修改符,常量池等),从而导致OOM

   个人经验:

     控制对象数量,让对象快速被回收

 

  4、本机直接内存溢出

   本人没遇到过,似乎很少会有这种OOM

 

四、总结

  避免OOM的本质是让对象尽可能多的只存活在Eden区,避免长时间持有对象,避免创建大量对象,提高GC运行效率

   

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值