聊聊3种内存溢出OOM(OutOfMemory)

58 篇文章 0 订阅
30 篇文章 2 订阅
内存溢出有3种,我们最熟悉的就是堆内存溢出异常,比如我们new一个对象或者数组,如果超出了JVM的heap内存最大限制就会爆出异常
比如:






从这句话我们可以知道,栈内存溢出有2种异常一种是:StackOverflowError、另一种是OutOfMemoryError


StackOverflowError是指【线程】的栈内存不足,导致【线程】抛出了StackOverflowError。
线程的stack是线程独有的,默认大小通常1M,可以通过-Xss来设置,比如-Xss128k,-Xss越大,则线程获得栈内存越大,越难出现栈内存溢出。不过从经验上来讲,1M的栈内存是足够的,如果还出现栈内存溢出,就只能说明程序有问题,常见的就是在线程内过度的进行函数调用,函数调用会消耗栈空间,比如拼命的进行递归调用,这个时候你得考虑在算法上做优化了。

下面是代码演示(仅供参考):





递归函数调用栈开避了7493开始发现Main线程的栈空间不足,所以抛出了main线程的栈空间不足的异常




如果我把-Xss2m那么可开避的函数调用栈会差不多翻一倍






而JVM虚拟机本质上是操作系统上的一个进程,所以他也拥有自己的系统堆空间和栈空间。
JVM的栈空间被所有线程分割成一块一块的,每个线程只占用一块。而JVM的栈空间的最小分配单位由-Xss来决定,没错,-Xss有两个语义, 即定义了每个线程的栈大小,也定义了虚拟机的最小栈内存的分配单位。我们甚至可以估算出,虚拟机可以创建的最大线程数,即操作系统可以分配给进程的最大栈空间大小除以-Xss的值,就可以得到最大活跃线程数。如果先申请的线程没有栈空间可以分配了就会抛出 OutOfMemoryError。表示【JVM虚拟机】的栈空间不足,溢出异常。

下面是演示代码(注意,这个实验可以能会因为JVM申请太多栈内存,导致操作系统因为栈空间不足出现假死。我的内存16G,所以妥妥的):



代码中我设置了-Xss1m
我开启了N多个线程,然后让所有线程等待(持有栈空间,不释放)。

你会发现很快抛出了异常。


如果我设置为-Xss128k
你会发现要等很久才会抛出异常,因为每个线程才128K,所以可以分配的线程变多了,所以for又多运行了几次,才没那么快死机。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值