JVM堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作的問(wèn)題解析
最近網(wǎng)上出現(xiàn)一個(gè)美團(tuán)面試題:“一個(gè)線程O(píng)OM后,其他線程還能運(yùn)行嗎?”。我看網(wǎng)上出現(xiàn)了很多不靠譜的答案。這道題其實(shí)很有難度,涉及的知識(shí)點(diǎn)有jvm內(nèi)存分配、作用域、gc等,不是簡(jiǎn)單的是與否的問(wèn)題。
由于題目中給出的OOM,java中OOM又分很多類(lèi)型;比如:堆溢出(“java.lang.OutOfMemoryError: Java heap space”)、永久帶溢出(“java.lang.OutOfMemoryError:Permgen space”)、不能創(chuàng)建線程(“java.lang.OutOfMemoryError:Unable to create new native thread”)等很多種情況。
本文主要是分析堆溢出對(duì)應(yīng)用帶來(lái)的影響。
先說(shuō)一下答案,答案是還能運(yùn)行。
代碼如下
public class JvmThread { public static void main(String[] args) { new Thread(() -> { List<byte[]> list = new ArrayList<byte[]>(); while (true) { System.out.println(new Date().toString() + Thread.currentThread() + "=="); byte[] b = new byte[1024 * 1024 * 1]; list.add(b); try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }).start(); // 線程二 new Thread(() -> { while (true) { System.out.println(new Date().toString() + Thread.currentThread() + "=="); try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } }).start(); } }
結(jié)果展示:
Wed Nov 07 14:42:18 CST 2018Thread[Thread-1,5,main]== Wed Nov 07 14:42:18 CST 2018Thread[Thread-0,5,main]== Wed Nov 07 14:42:19 CST 2018Thread[Thread-1,5,main]== Wed Nov 07 14:42:19 CST 2018Thread[Thread-0,5,main]== Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space at com.gosaint.util.JvmThread.lambda$main$0(JvmThread.java:21) at com.gosaint.util.JvmThread$$Lambda$1/521645586.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Wed Nov 07 14:42:20 CST 2018Thread[Thread-1,5,main]== Wed Nov 07 14:42:21 CST 2018Thread[Thread-1,5,main]== Wed Nov 07 14:42:22 CST 2018Thread[Thread-1,5,main]==
JVM啟動(dòng)參數(shù)設(shè)置:
上圖是JVM堆空間的變化。我們仔細(xì)觀察一下在14:42:05~14:42:25之間曲線變化,你會(huì)發(fā)現(xiàn)使用堆的數(shù)量,突然間急劇下滑!這代表這一點(diǎn),當(dāng)一個(gè)線程拋出OOM異常后,它所占據(jù)的內(nèi)存資源會(huì)全部被釋放掉,從而不會(huì)影響其他線程的運(yùn)行!
講到這里大家應(yīng)該懂了,此題的答案為一個(gè)線程溢出后,進(jìn)程里的其他線程還能照常運(yùn)行。注意了,這個(gè)例子我只演示了堆溢出的情況。如果是棧溢出,結(jié)論也是一樣的,大家可自行通過(guò)代碼測(cè)試。
總結(jié):其實(shí)發(fā)生OOM的線程一般情況下會(huì)死亡,也就是會(huì)被終結(jié)掉,該線程持有的對(duì)象占用的heap都會(huì)被gc了,釋放內(nèi)存。因?yàn)榘l(fā)生OOM之前要進(jìn)行g(shù)c,就算其他線程能夠正常工作,也會(huì)因?yàn)轭l繁gc產(chǎn)生較大的影響。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)電話(huà)本系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)電話(huà)本系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Java在PowerPoint中添加上標(biāo)和下標(biāo)的實(shí)現(xiàn)方法
當(dāng)我們?cè)谘菔疚母逯刑砑由虡?biāo)、版權(quán)或其他符號(hào)時(shí),我們可能希望該符號(hào)出現(xiàn)在某個(gè)文本的上方或下方。在Microsoft PowerPoint中,我們可以通過(guò)對(duì)符號(hào)應(yīng)用上標(biāo)或下標(biāo)格式來(lái)實(shí)現(xiàn)這種效果,這篇文章主要介紹了Java在PowerPoint中添加上標(biāo)和下標(biāo),需要的朋友可以參考下2022-10-10Springboot如何同時(shí)裝配兩個(gè)相同類(lèi)型數(shù)據(jù)庫(kù)
這篇文章主要介紹了Springboot如何同時(shí)裝配兩個(gè)相同類(lèi)型數(shù)據(jù)庫(kù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Spring Boot實(shí)現(xiàn)文件上傳示例代碼
本篇文章主要介紹了Spring Boot實(shí)現(xiàn)文件上傳示例代碼,可以實(shí)現(xiàn)單文件和多文件的上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03Spring Security賬戶(hù)與密碼驗(yàn)證實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了Spring Security賬戶(hù)與密碼驗(yàn)證實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-03-03Java?DelayQueue實(shí)現(xiàn)任務(wù)延時(shí)示例講解
DelayQueue是一個(gè)無(wú)界的BlockingQueue的實(shí)現(xiàn)類(lèi),用于放置實(shí)現(xiàn)了Delayed接口的對(duì)象,其中的對(duì)象只能在其到期時(shí)才能從隊(duì)列中取走。本文就來(lái)利用DelayQueue實(shí)現(xiàn)延時(shí)任務(wù),感興趣的可以了解一下2022-09-09Java處理圖片實(shí)現(xiàn)base64編碼轉(zhuǎn)換
這篇文章主要介紹了Java處理圖片實(shí)現(xiàn)base64編碼轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02SpringMVC加載控制與Postmand的使用和Rest風(fēng)格的引入及RestFul開(kāi)發(fā)全面詳解
SpringMVC是一種基于Java,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類(lèi)型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦。基于請(qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開(kāi)發(fā),SpringMVC也是要簡(jiǎn)化我們?nèi)粘eb開(kāi)發(fā)2022-10-10