JVM(7)——OOM内存溢出

1.什么是内存溢出?在哪些区域会发生内存溢出

内存溢出指程序申请内存时,没有足够的内存供申请者使用

第一块Metaspace区域里可能发生OOM

第二块可能发生OOM的区域,就是每个线程的虚拟机栈内存。

第三块可能发生内存溢出的区域,就是堆内存空间!

2.Metaspace区域是如何触发内存溢出的?

如下两个参数就是用来设置Metaspace区域大小的:

-XX:MetaspaceSize=512m

-XX:MaxMetaspaceSize=512m

Metaspace区域满了,此时会触发Full GC,连带着回收Metaspace里的类。但是类被回收前提是有三个条件的,满足不了三个条件回收不了多少类,此时你的JVM还在拼命的加载类放到Metaspace里去就会引发内存溢出的问题。

3.到底什么情况下会发生Metaspace内存溢出?

Metaspace这块区域一般很少发生内存溢出,如果发生内存溢出一般都是因为两个原因:

  1. 在上线系统的时候对Metaspace区域直接用默认的参数,即根本不设置其大小这会导致默认的Metaspace区域可能才几十MB而已
  2. 系统的时候会用cglib之类的技术动态生成一些类,一旦代码中没有控制好,导致你生成的类过于多的时候,就很容易把Metaspace给塞满,进而引发内存溢出

怎么解决?

对于第一种问题,通常来说,有经验的工程师上线系统往往会设置对应的Metaspace大小,推荐的值在512MB那样,一般都是足够的。

4什么情况下会发生线程的栈内存溢出?

每次方法调用的栈桢都是要占用内存的一个线程调用多个方法的会入栈和出栈

既然一个线程的虚拟机栈内存大小是有限的,比如1MB,那么假设你不停的让这个线程去调用各种方法,然后不停的把方法调用的栈桢压入栈中,此时终有一个时刻,大量的栈桢会消耗完毕这个1MB的线程栈内存,最终就会导致出现栈内存溢出的情况。

无限制的方法递归

5.到底什么情况下会发生堆内存溢出?
  1. 系统承载高并发请求,因为请求量过大,导致大量对象都是存活的,所以要继续放入新的对象实在是不行了,此时就会引发OOM系统崩溃
  2. 系统有内存泄漏的问题,就是莫名其妙弄了很多的对象,结果对象都是存活的,没有及时取消对他们的引用,导致触发GC还是无法回收,此时只能引发内存溢出,因为内存实在放不下更多对象了

因此总结起来,一般引发OOM,要不然是系统负载过高,要不然就是有内存泄漏的问题

6如何在JVM内存溢出的时候自动dump内存快照?
  1. 在OOM的时候自动dump内存快照
    在JVM的启动参数中加入如下的一些参数:

    -XX:+HeapDumpOnOutOfMemoryError

    -XX:HeapDumpPath=/usr/local/app/oom
    第一个参数意思是在OOM的时候自动dump内存快照出来,第二个参数是说把内存快照放到哪儿去

  2. 发生OOM,用MAT工具来分析Metaspace、栈内存、堆内存三种内存溢出下的内存快照文件

7.如何对对线上系统的OOM异常进行监控和报警

一种是通过监控系统,一种是被动等待系统挂掉后客服来通知你

8.堆内存溢出的问题如何分析和定位?
  1. 必须在JVM参数中加入自动导出内存快照,一个是到线上看一下日志文件里的报错,如果是堆溢出,立马用MAT分析内存快照。
  2. 先看占用内存最多的对象是谁,然后分析那个线程的调用栈,接着就可以看到是哪个方法引发的内存溢出了接着优化代码即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值