日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

我也来说说经典面试题目-“OOM异常会导致JVM退出吗?”

發布時間:2025/5/22 编程问答 22 如意码农
生活随笔 收集整理的這篇文章主要介紹了 我也来说说经典面试题目-“OOM异常会导致JVM退出吗?” 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

經典面試題目“OOM異常會導致JVM退出嗎?

我的回答是“這要分情況看,對于守護線程來說,OOM并不會導致JVM退出;對于非守護線程來說,如果某個線程捕獲了OOM異常并正確進行了處理,那JVM并不會退出;如果線程沒有捕獲異常,那么將由全局的異常處理器處理,默認的全局的異常處理器也會讓當前這個發生異常的線程退出,但是如果這個線程是最后一個非守護線程,那么JVM會退出,如果不是,JVM并不會退出。

對于守護線程來說,OOM并不會導致JVM退出,這里有一個非常好的線上故障:https://blog.csdn.net/shuxiaohua/article/details/114658325 ,缺少的接收客戶端請求的線程Acceptor是一個守護線程,并且因為OOM退出時,并沒有讓Tomcat退出。

下面介紹一下非守護線程的情況,這些非守護線程通常就是處理業務的線程。每一個寫過Java的人都應該知道Java異常繼承體系,如下圖所示。

這里我們要注意一點,就是Exception和Error有共同的父類Throwable,這意味著異常和錯誤都可以在Java層捕獲,例如:

public static void main(String[] args) throws InterruptedException {
try{
// 每個整數數組的大小為4M
int[] array1 = new int[1_000_000];
int[] array2 = new int[1_000_000];
int[] array3 = new int[1_000_000];
int[] array4 = new int[1_000_000];
int[] array5 = new int[1_000_000];
}catch (Throwable t){
t.printStackTrace();
}
System.out.println("程序走到了這里!");
}

我們在指定參數-Xms20M -Xmx20m后,運行打印結果如下:

java.lang.OutOfMemoryError: Java heap space
at cn.hotspotvm.TestError.main(TestError.java:12)
程序走到了這里!

可以看到,即使發生了錯誤,這個線程依然在正常運行,如果我們不對Error進行捕獲呢?如下:

public static void main(String[] args) throws InterruptedException {
int[] array1 = new int[1_000_000];
int[] array2 = new int[1_000_000];
int[] array3 = new int[1_000_000];
int[] array4 = new int[1_000_000];
int[] array5 = new int[1_000_000];
System.out.println("程序走到了這里!");
}

再次運行后就的打印結果如下:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at cn.hotspotvm.TestError.main(TestError.java:10)

可以看到,在發生錯誤時這個線程沒有走到打印語句,而是直接退出了。

這里其實要說明的是,我們可以設置一個全局的異常處理器來統一處理,或者優先針對某個線程設置異常處理器,這樣當我們忽略了捕獲錯誤時,可以在全局異常處理器中進行處理。舉個例子如下:

public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("這里是全局異常處理 "+e.getLocalizedMessage());
}
}); int[] array1 = new int[1_000_000];
int[] array2 = new int[1_000_000];
int[] array3 = new int[1_000_000];
int[] array4 = new int[1_000_000];
int[] array5 = new int[1_000_000]; System.out.println("程序走到了這里!");
}

打印的信息如下:

這里是全局異常處理 Java heap space

這個線程在全局異常處理中如果沒有特殊處理,通常會讓當前的線程退出。如果當前線程退出,那么JVM會退出嗎?

其實Java虛擬機退出的條件是:虛擬機內已經沒有了非守護線程。線程發生未處理的異常最終導致線程結束時,如果這個線程是最后一個非守護線程,則會退出,否則不退出。

更多文章可訪問:JDK源碼剖析網

 

總結

以上是生活随笔為你收集整理的我也来说说经典面试题目-“OOM异常会导致JVM退出吗?”的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。