模拟JAVA堆内存溢出和栈内存溢出
文章目錄
- 1. 模擬堆內(nèi)存溢出
- 2. 模擬棧內(nèi)存溢出
1. 模擬堆內(nèi)存溢出
為了更快的出現(xiàn)堆內(nèi)存溢出,可以限制Java堆的大小為10MB(不限制也可以)。代碼如下(可直接復(fù)制使用):
package test.oom;import java.util.ArrayList; import java.util.List;// VM Args:-Xms10m -Xmx10m public class HeapOOM {static class OOMObject {}public static void main(String[] args) {List<OOMObject> list = new ArrayList<>();while (true) {list.add(new OOMObject());}} }運(yùn)行結(jié)果:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.base/java.util.Arrays.copyOf(Arrays.java:3511)at java.base/java.util.Arrays.copyOf(Arrays.java:3480)at java.base/java.util.ArrayList.grow(ArrayList.java:237)at java.base/java.util.ArrayList.grow(ArrayList.java:244)at java.base/java.util.ArrayList.add(ArrayList.java:454)at java.base/java.util.ArrayList.add(ArrayList.java:467)at test.oom.HeapOOM.main(HeapOOM.java:14)Process finished with exit code 1當(dāng)申請(qǐng)不到堆內(nèi)存,總?cè)萘坑|及最大堆的容量限制后就會(huì)產(chǎn)生堆內(nèi)存溢出異常。Java堆內(nèi)存的OutOfMemoryError異常是實(shí)際應(yīng)用中最常見(jiàn)的內(nèi)存溢出異常情況。出現(xiàn)Java堆內(nèi)存 溢出時(shí),異常堆棧信息“java.lang.OutOfMemoryError”會(huì)跟隨進(jìn)一步提示“Java heap space”。
要解決這個(gè)內(nèi)存區(qū)域的異常,常規(guī)的處理方法是首先通過(guò)內(nèi)存映像分析工具(如Eclipse Memory Analyzer)對(duì)Dump出來(lái)的堆轉(zhuǎn)儲(chǔ)快照進(jìn)行分析。首先應(yīng)確認(rèn)內(nèi)存中導(dǎo)致OOM的對(duì)象是否是必要的,也就是要先分清楚到底是出現(xiàn)了內(nèi)存泄漏(Memory Leak)還是內(nèi)存溢出(Memory Overflow)。如果是內(nèi)存溢出且代碼沒(méi)問(wèn)題,就需要擴(kuò)大堆內(nèi)存;如果是內(nèi)存泄漏一般需要查看自己代碼。
2. 模擬棧內(nèi)存溢出
模擬棧內(nèi)存溢出,可以參考如下代碼(可直接復(fù)制使用):
package test.oom;public class StackOOM {private int stackLength = 1;public void stackLeak() {stackLength++;stackLeak();}public static void main(String[] args) throws Throwable {StackOOM oom = new StackOOM();try {oom.stackLeak();} catch (Throwable e) {System.out.println("stack length:" + oom.stackLength);throw e;}} }運(yùn)行結(jié)果:
stack length:16073(機(jī)器和配置不同,這個(gè)值會(huì)不同) Exception in thread "main" java.lang.StackOverflowErrorat test.oom.StackOOM.stackLeak(StackOOM.java:8)at test.oom.StackOOM.stackLeak(StackOOM.java:8)......(省略了相同的日志)at test.oom.StackOOM.stackLeak(StackOOM.java:8)at test.oom.StackOOM.stackLeak(StackOOM.java:8)Process finished with exit code 1可以看到出現(xiàn)了StackOverflowError,關(guān)于虛擬機(jī)棧和本地方法棧,在《Java虛擬機(jī)規(guī)范》中描述了兩種異常:
2.1 如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的最大深度,將拋出StackOverflowError異常。
2.2 如果虛擬機(jī)的棧內(nèi)存允許動(dòng)態(tài)擴(kuò)展,當(dāng)擴(kuò)展棧容量無(wú)法申請(qǐng)到足夠的內(nèi)存時(shí),將拋出 OutOfMemoryError異常。
這個(gè)例子是棧深度大于虛擬機(jī)所允許的最大深度,方法執(zhí)行是利用棧來(lái)實(shí)現(xiàn)的。
總結(jié)
以上是生活随笔為你收集整理的模拟JAVA堆内存溢出和栈内存溢出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: B端产品如何搭建用户帮助体系
- 下一篇: slice和splice数组的截取/sp