JVM中哪些内存区域会发生内存溢出

栈(虚拟机栈)溢出

栈,一般指的是虚拟机栈。你启动一个线程,它会启动一个虚拟机栈。

但是这个虚拟机栈的大小是固定的。栈的大小默认值是1M。

在线程的执行过程中间,栈是用来存储Java运行时方法所需的数据、指令还有返回地址。

例如你运行A方法,A方法里面的数据指令还有返回地址等,它会作为一个栈帧压入到这个虚拟机栈当中。再调用B方法的时候,这个时候A没有运行完,A运行过程中调用了B方法,这个时候又会往虚拟机栈中去压一个栈帧。

如果方法区进行这种递归调用,这个时候栈就有可能会爆掉,并抛出StackOverFlowError的异常,就是我们常见的栈溢出。

其实,在虚拟机当中,只会对虚拟机栈的大小,把它限定到大概是1M。默认情况下是1M。

然后不断地往里面去压入,如果我们的方法去进行这种递归调用,这个时候栈就会爆掉。栈爆掉之后就会抛出一个异常,StackOverflowError,也就是我们常见的栈溢出。

堆溢出

在JVM中间,几乎所有的对象都是在堆中间分配。然后堆空间如果满了的话,就会触发GC。但是如果你不断地往堆空间中分配对象,然后你触发的垃圾回收却没有回收到对应的效果。

比方说你每秒钟要往堆空间中分配100M的对象,但是这个时候你发现你的堆空间中剩余空间只有50个,那么系统会发生垃圾回收。

可能垃圾回收只能给你腾出总共70M的大小,这样的话,这个对象就分配不进去了。

然后就会发生内存溢出,也就是我们常见的Out Of Memory(OOM)。

方法区溢出

JDK1.7中就是永久代,JDK1.8就是元空间。

本机直接内存(堆外内存)溢出

JVM中有一块区域称为运行时数据区,运行时数据区里面有栈、堆、方法区还有等等其他的。

比方说,你的机器是16G,那么这些区域可能占据了8个G,那么机器上还剩余8个G。

所以在Java中,这8个G可以直接进行分配。这块内存我们称为直接内存。也有别的说法,称为堆外内存。

这块区域内存需要手动申请、手动释放,但是这一块还是会受制于Java虚拟机的一些参数。

补充

不会发生OOM的区域(唯一的):程序计数器

参考资料每天一个知识点:【两分钟带你了解并发相关】JVM中哪些内存区域会发生内存溢出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值