12、OOM简介

OOM,Out Of Memory,内存溢出,发生内存溢出是会导致JVM挂掉的。

在我们启动JVM的时候,指定了一些内存参数,JVM内存大小是有限的,如果不停地往里面放东西,那么在一定情况下就会发生OOM。

那我们具体来看一看哪些区域会发生OOM,以及分别在什么条件下会发生OOM。

JVM内存区域可以划分为:方法区(元数据区),堆内存,虚拟机栈,本地方法栈,程序计数器。

程序计数器:

其中程序计数器,是每个线程私有,而且就算保存一个字节码执行的地址,不存在内存溢出的情况。

虚拟机栈:

虚拟机栈也是线程私有,里面存放的是一个一个栈帧,对应一个又一个方法的执行,出栈之后自动消失,也不存在内存溢出的情况,但是当无限入栈的时候,会导致栈溢出:Stack Over Flow。一般每个线程的栈大小为500KB,或1MB,一个栈帧大小为1KB,那么除非一个线程在执行过程中调用了500个方法,或是1000个方法,但正常代码的调用链绝不可能这么深,更通常的导致Stack Over Flow的原因在于方法自调用:

public void test(){

System.out.println(“test here”);

test();

}

像这样,就会导致执行到test()方法的线程无限入栈,最终导致Stack Over Flow。

元数据区:

元数据区里面存放了JVM运行过程中通过类加载器加载进去的所有类。当元数据区满了的时候会触发Full GC,Full GC的时候会回收元数据区里面的类,但是要回收一个类,条件失非常苛刻的:这个类的类加载器要先被回收,这个类的所有实例对象都要先被回收等等。如果Full GC之后元数据区还是满的,此时继续往里面放新的东西,则会触发OOM。

元数据区发生OOM的原因在于两个:

第一种原因:很多工程师不懂JVM的运行原理,没有设置元数据区大小,在上线系统的时候直接使用了默认的元数据区大小,但是对于一些大型系统来说,自身有很多的类要加载,以及依赖了较多的jar包,jar包中的类也要加载,最终导致,元数据区容纳不下需要加载的类,导致OOM。

第二种原因:很多人写代码的时候,会通过cglib之类的技术动态生成一个代理类,一旦代码没有控制好,那么就可能导致生成的类太多,本来只需要生成一个类对象即可,结果每次请求都需要生成一个类,最终导致元数据区里面放了太多cglib动态生成的类,导致元数据区OOM。

堆内存:

堆内存存放了所有创建的对象,而堆内存划分为了新生代和老年代,新生代在 Young GC之后,即使Survivor区放不下,也还是有老年代来提供空间担保,所以新生代是不会发生OOM。但是老年代在进行了Full GC之后,如果还是没有足够的空间来存放Young GC之后的对象,则会发生堆内存的OOM。

老年代发生OOM的原因:

第一个原因:系统承载的并发量太大,导致大量请求还处于正在处理中的状态,大量对象的引用还没有失去,大量对象存活,Young GC后放入老年代,Full GC后还是没有回收多少,继续Young GC后放入老年代,老年代OOM。

第二个原因:系统有内存泄漏的问题。在java中的内存泄漏指的是:一些对象本来已经不再会被使用到了,但是这样的对象还是有引用。导致GC时无法对这些对象进行回收,从而导致OOM。

1、JVM是如何工作的?_jerry_dyy的博客-CSDN博客_jvm是如何运行的

2、JVM的类加载机制_jerry_dyy的博客-CSDN博客

3、JVM内存区域划分_jerry_dyy的博客-CSDN博客_jvm的内存区域划分

4、JVM垃圾回收机制_jerry_dyy的博客-CSDN博客

5、JVM分代模型--新生代 的垃圾回收_jerry_dyy的博客-CSDN博客_jvm新生代划分

6、JVM分代模型--老年代 的垃圾回收_jerry_dyy的博客-CSDN博客

7、常见的垃圾回收器_jerry_dyy的博客-CSDN博客

8、JVM优化简介_jerry_dyy的博客-CSDN博客

9、学会查看GC日志_jerry_dyy的博客-CSDN博客

10、摸清JVM运行状况_jerry_dyy的博客-CSDN博客

11、摸清JVM对象分布_jerry_dyy的博客-CSDN博客

12、OOM简介_jerry_dyy的博客-CSDN博客

13、OOM模拟_jerry_dyy的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值