JVM内存溢出分析:堆内存溢出+虚拟机,线程池底层原理面试

*/

public class HeapOOM {

static class OOMObject {

}

public static void main(String[] args) {

List oomObjectList = new ArrayList<>();

while (true) {

oomObjectList.add(new OOMObject());

}

}

}

运行后会报异常,在堆栈信息中可以看到:

java.lang.OutOfMemoryError: Java heap space 的信息,说明在堆内存空间产生内存溢出的异常。

新产生的对象最初分配在新生代,新生代满后会进行一次 Minor GC,如果 Minor GC 后空间不足会把该对象和新生代满足条件的对象放入老年代,老年代空间不足时会进行 Full GC,之后如果空间还不足以存放新对象则抛出 OutOfMemoryError 异常。

常见原因:内存中加载的数据过多如一次从数据库中取出过多数据;集合对对象引用过多且使用完后没有清空;代码中存在死循环或循环产生过多重复对象;堆内存分配不合理;网络连接问题、数据库问题等。

2、虚拟机栈/本地方法栈溢出

(1)StackOverflowError:当线程请求的栈的深度大于虚拟机所允许的最大深度,则抛出StackOverflowError,简单理解就是虚拟机栈中的栈帧数量过多(一个线程嵌套调用的方法数量过多)时,就会抛出StackOverflowError异常。

最常见的场景就是方法无限递归调用,如下:

/**

设置每个线程的栈大小:-Xss256k

运行时,不断调用doSomething()方法,main线程不断创建栈帧并入栈,导致栈的深度越来越大,最终导致栈溢出。

*/

public class StackSOF {

private int stackLength=1;

public void doSomething(){

stackLength++;

doSomething();

}

public static void main(String[] args) {

StackSOF stackSOF=new StackSOF();

try {

stackSOF.doSomething();

}catch (Throwable e){//注意捕获的是Throwable

System.out.println(“栈深度:”+stackSOF.stackLength);

throw e;

}

}

}

上述代码执行后抛出:

Exception in thread “Thread-0” java.lang.StackOverflowError 的异常。

(2)OutOfMemoryError:如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出 OutOfMemoryError。

我们可以这样理解,虚拟机中可以供栈占用的空间≈可用物理内存 - 最大堆内存 - 最大方法区内存,比如一台机器内存为 4G,系统和其他应用占用 2G,虚拟机可用的物理内存为 2G,最大堆内存为 1G,最大方法区内存为 512M,那可供栈占有的内存大约就是 512M,假如我们设置每个线程栈的大小为 1M,那虚拟机中最多可以创建 512个线程,超过 512个线程再创建就没有空间可以给栈了,就报 OutOfMemoryError 异常了。

image

栈上能够产生 OutOfMemoryError 的示例如下:

/**

设置每个线程的栈大小:-Xss2m

运行时,不断创建新的线程(且每个线程持续执行),每个线程对一个一个栈,最终没有多余的空间来为新的线程分配,导致OutOfMemoryError

*/

public class StackOOM {

private static int threadNum = 0;

public void doSomething() {

try {

Thread.sleep(100000000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

final StackOOM stackOOM = new StackOOM();

try {

while (true) {

threadNum++;

Thread thread = new Thread(new Runnable() {

@Override

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

最新整理面试题
在这里插入图片描述

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

在这里插入图片描述

最新整理大厂面试文档

在这里插入图片描述

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

最新整理面试题
[外链图片转存中…(img-2bDHyp1P-1711057527198)]

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

[外链图片转存中…(img-2kZAAJjn-1711057527198)]

最新整理大厂面试文档

[外链图片转存中…(img-IBiM1oyC-1711057527199)]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值