大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 探究JVM棧溢出

探究JVM棧溢出

更新時間:2020-10-10 17:29:38 來源:動力節(jié)點 瀏覽1254次

由于在HotSpot虛擬機中并不區(qū)分JVM棧和本地方法棧,因此,對于HotSpot來說,雖然-Xoss參數(設置本地方法棧大小)存在,但實際上是無效的,棧容量只由-Xss參數設定。下面我們來通過實例探究一下JVM棧溢出的情況。


關于虛擬機棧和本地方法棧,在Java虛擬機規(guī)范中描述了兩種異常:

如果線程請求的棧深度大于虛擬機所允許的最大深度,將拋出StackOverflowError異常。

如果虛擬機在擴展棧時無法申請到足夠的內存空間,則拋出OutOfMemoryError異常。


這里把異常分成兩種情況,看似更加嚴謹,但卻存在著一些互相重疊的地方:當??臻g無法繼續(xù)分配時,到底是內存太小,還是已使用的??臻g太大,其本質上只是對同一件事情的兩種描述而已。


使用-Xss參數減少棧內存容量。結果:拋出StackOverflowError異常,異常出現時輸出的堆棧深度相應縮小。

定義了大量的本地變量,增大此方法幀中本地變量表的長度。結果:拋出StackOverflowError異常時輸出的堆棧深度相應縮小。

代碼如下:

/**

* VM Args:-Xss128k

* @author zzm

*/

public class JavaVMStackSOF {

private int stackLength = 1;

public void stackLeak() {

stackLength++;

stackLeak();

}

public static void main(String[] args) throws Throwable {

JavaVMStackSOF oom = new JavaVMStackSOF();

try {

oom.stackLeak();

} catch (Throwable e) {

System.out.println("stack length:" + oom.stackLength);

throw e;

}

}

}


運行結果:

stack length :2402

Exception in thread"main"java.lang.StackOverflowError

at org.fenixsoft.oom.VMStackSOF.leak (WIStackSOF.java :20 ) at org.fenixsoft.oom.VMStackSOF.leak (WIStackSOF.java :21 ) at org.fenixsoft.oom.VMStackSOF.leak (WIStackSOF.iava :21 )

.....后續(xù)異常堆棧信息省略


實驗結果表明:在單個線程下,無論是由于棧幀太大還是虛擬機棧容量太小,當內存無法分配的時候,虛擬機拋出的都是StackOverflowError異常。


如果測試時不限于單線程,通過不斷地建立線程的方式倒是可以產生內存溢出異常。但是這樣產生的內存溢出異常與棧空間是否足夠大并不存在任何聯(lián)系,或者準確地說,在這種情況下,為每個線程的棧分配的內存越大,反而越容易產生內存溢出異常。

其實原因不難理解,操作系統(tǒng)分配給每個進程的內存是有限制的,譬如32位的Windows限制為2GB。虛擬機提供了參數來控制Java堆和方法區(qū)的這兩部分內存的最大值。剩余的內存為2GB(操作系統(tǒng)限制)減去Xmx(最大堆容量),再減去MaxPermSize(最大方法區(qū)容量),程序計數器消耗內存很小,可以忽略掉。如果虛擬機進程本身耗費的內存不計算在內,剩下的內存就由虛擬機棧和本地方法?!肮戏帧绷恕C總€線程分配到的棧容量越大,可以建立的線程數量自然就越少,建立線程時就越容易把剩下的內存耗盡。


這一點讀者需要在開發(fā)多線程的應用時特別注意,出現StackOverflowError異常時有錯誤堆??梢蚤喿x,相對來說,比較容易找到問題的所在。而且,如果使用虛擬機默認參數,棧深度在大多數情況下(因為每個方法壓入棧的幀大小并不是一樣的,所以只能說在大多數情況下)達到1000~2000完全沒有問題,對于正常的方法調用(包括遞歸),這個深度應該完全夠用了。但是,如果是建立過多線程導致的內存溢出,在不能減少線程數或者更換64位虛擬機的情況下,就只能通過減少最大堆和減少棧容量來換取更多的線程。如果沒有這方面的處理經驗,這種通過“減少內存”的手段來解決內存溢出的方式會比較難以想到。


代碼如下:創(chuàng)建線程導致內存溢出異常

/**

* VM Args:-Xss2M (這時候不妨設大些)

* @author zzm

*/

public class JavaVMStackOOM {

private void dontStop() {

while (true) {

}

}

public void stackLeakByThread() {

while (true) {

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

dontStop();

}

});

thread.start();

}

}

public static void main(String[] args) throws Throwable {

JavaVMStackOOM oom = new JavaVMStackOOM();

oom.stackLeakByThread();

}

}


注意,特別提示一下,如果要嘗試運行上面這段代碼,記得要先保存當前的工作。由于在Windows平臺的虛擬機中,Java的線程是映射到操作系統(tǒng)的內核線程上的,因此上述代碼執(zhí)行時有較大的風險,可能會導致操作系統(tǒng)假死。


運行結果:

Exception in thread"main"java.lang.OutOfMemoryError :unable to create new native thread


以上就是我們對JVM棧溢出的探究過程,想要了解JVM棧溢出背后涉及到的更多的知識,可以觀看本站的Java零基礎教程,全面提升自己的Java基礎。


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 国产黄毛片 | 午夜宅男在线观看 | 欧美影院一区二区 | 午夜宅男免费完整在线观看 | 国产精品日韩欧美在线第3页 | 久久最稳定资源站在线 | 日本一区二区三区高清在线观看 | 久久综合九色综合亚洲小说 | 国产日韩不卡免费精品视频 | 四虎最新永久免费视频 | 久久亚洲国产精品五月天婷 | 老司机午夜免费福利 | 四虎在线免费 | 亚洲国产99在线精品一区69堂 | 视频一区二区国产 | 精品福利国产 | 激性欧美激情在线播放16页 | 日韩一区二区三区免费 | 日韩不卡视频在线 | 性成人动作片在线看 | 久久99精品国产麻豆婷婷 | 成人久久18免费网站游戏 | 久久青草视频 | 久草热线视频 | 欧美精 | 成人久久精品 | 久久这里只有精品2 | 国产在线播放成人免费 | 日韩最新中文字幕 | 四虎永久免费地址ww417 | 久久9966精品国产免费 | 女人十八毛片免费观 | 特级aaa毛片 | 亚洲在线视频免费 | 亚洲18岁禁止 | 五十路一区二区三区视频 | 欧美亚洲另类图片 | 日日舔 | 亚洲最大成人综合网 | 夜夜操操操 | 日本三级欧美三级 |