1. 程式人生 > >某團面試題:JVM 堆記憶體溢位後,其他執行緒是否可繼續工作?

某團面試題:JVM 堆記憶體溢位後,其他執行緒是否可繼續工作?

轉載註明:http://dwz.win/gHc
最近網上出現一個美團面試題:“一個執行緒OOM後,其他執行緒還能執行嗎?”。我看網上出現了很多不靠譜的答案。這道題其實很有難度,涉及的知識點有jvm記憶體分配、作用域、gc等,不是簡單的是與否的問題。

由於題目中給出的OOM,java中OOM又分很多型別;比如:堆溢位(“java.lang.OutOfMemoryError: Java heap space”)、永久帶溢位(“java.lang.OutOfMemoryError:Permgen space”)、不能建立執行緒(“java.lang.OutOfMemoryError:Unable to create new native thread”)等很多種情況。

本文主要是分析堆溢位對應用帶來的影響。

先說一下答案,答案是還能執行。

程式碼如下

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();
    }
}

結果展示:

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啟動引數設定:


上圖是JVM堆空間的變化。我們仔細觀察一下在14:42:05~14:42:25之間曲線變化,你會發現使用堆的數量,突然間急劇下滑!這代表這一點,當一個執行緒丟擲OOM異常後,它所佔據的記憶體資源會全部被釋放掉,從而不會影響其他執行緒的執行!

講到這裡大家應該懂了,此題的答案為一個執行緒溢位後,程序裡的其他執行緒還能照常執行。注意了,這個例子我只演示了堆溢位的情況。如果是棧溢位,結論也是一樣的,大家可自行通過程式碼測試。

總結:其實發生OOM的執行緒一般情況下會死亡,也就是會被終結掉,該執行緒持有的物件佔用的heap都會被gc了,釋放記憶體。因為發生OOM之前要進行gc,就算其他執行緒能夠正常工作,也會因為頻繁gc產生較大的影響。

覺得文章不錯的歡迎關注我的WX公眾號:程式設計師喬戈裡
我是百度後臺開發工程師,哈工大計算機本碩,專注分享技術乾貨/程式設計資源/求職面試/成長感悟等,關注送5000G程式設計資源和自己整理的一份幫助不少人拿下java的offer的面經附答案,免費下載CSDN資源。

相關推薦

某團試題JVM 記憶體溢位其他執行是否繼續工作

轉載註明:http://dwz.win/gHc 最近網上出現一個美團面試題:“一個執行緒OOM後,其他執行緒還能執行嗎?”。我看網上出現了很多不靠譜的答案。這道題其實很有難度,涉及的知識點有jvm記憶體分配、作用域、gc等,不是簡單的是與否的問題。 由於題目中給出的OOM,java中OOM又分很多型別;比如:

jvm記憶體溢位其他執行是否繼續工作

    最近網上出現一個美團面試題:“一個執行緒OOM後,其他執行緒還能執行嗎?”。我看網上出現了很多不靠譜的答案。這道題其實很有難度,涉及的知識點有jvm記憶體分配、作用域、gc等,不是簡單的是與否的問題。     由於題目中給出的OOM,java中

今天做到一道試題關於記憶體與棧記憶體的區別

java中記憶體分配策略及堆和棧的比較   1 記憶體分配策略   按照編譯原理的觀點,程式執行時的記憶體分配有三種策略,分別是靜態的,棧式的,和堆式的.   靜態儲存分配是指在編譯時就能確定每個資料目標在執行時刻的儲存空間需求,因而在編譯時就可以給他們分配固定的記憶體空間.這種分配策略要求程式程式碼中

一道試題通過wait和notify的兩個執行互動輸出thread1-1...thread1-5thread2-6...thread2-10...

這是一道關於多執行緒的面試題,好久沒有做過這種多執行緒的題了,手有點生,那麼就來敲一敲 package threadDemo; /* * 多執行緒的交叉列印 */ public class

試題JVM在Java中對物件的建立、記憶體結構、訪問方式

  一、物件建立過程   1、檢查類是否已被載入     JVM遇到new指令時,首先會去檢查這個指令引數能否在常量池中定位到這個類的符號引用,檢查這個符號引用代表的類是否已被載入、解析、初始化,若沒有,則進行類載入   2、為新物件分配記憶體      類載入檢查後,JVM為新物件在堆記憶

記憶體溢位儲存記憶體快照-XX:+HeapDumpOnOutOfMemoryError

-XX:+HeapDumpOnOutOfMemoryError該配置會把快照儲存在使用者目錄或者tomcat目錄下,也可以通過 -XX:HeapDumpPath=/tmp/heapdump.hprof 來顯示指定路徑此外,OnOutOfMemoryError引數允許使用者指定

JAVA試題JVM+spring+分布式+並發編程+redis+網絡+設計模式!

發布 回收 靜態 系統 flow 實現負載均衡 函數 專題 高並發 此文包含 Java 面試的各個方面,史上最全,苦心整理最全Java面試題目整理包括Java基礎+JVM+算法+數據庫優化+算法數據結構+分布式+並發編程+緩存等,使用層面廣,知識量大,涉及你的知識盲點。要想

試題應用中很多jar包比如spring、mybatis、redis等等各自用的日誌系統各異怎麼用slf4j統一輸出?

一、問題概述 如題所說,後端應用(非spring boot專案)通常用到了很多jar包,比如spring系列、mybatis、hibernate、各類連線資料庫的客戶端的jar包。可能這個jar包用的是logback、那個用的是log4j、那個又是log4j2, 這時候,怎麼才能保證各jar包的日誌都能輸

試題應用中很多jar包比如spring、mybatis、redis等等各自用的日誌系統各異怎麽用slf4j統一輸出?

相同 如何 align 等等 version 試題 ava body jakarta 一、問題概述 如題所說,後端應用(非spring boot項目)通常用到了很多jar包,比如spring系列、mybatis、hibernate、各類連接數據庫的客戶端的jar包。可能這

【圖文詳細 】HDFS試題介紹Hadoop中RPC協議以及底層用什麼框架封裝的

用於將使用者請求中的引數或者應答轉換成位元組流以便跨機傳輸。 函式呼叫層:函式呼叫層主要功能是:定位要呼叫的函式,並執行該函式,Hadoop採用了java的反射機制和動態代理實現了函式的呼叫。 網路傳輸層:網路傳輸層描述了Client和Server之間訊息的傳輸方式,Hadoop採用了基

Hive試題hive有哪些udf函式作用

UDF(user-defined function)作用於單個數據行,產生一個數據行作為輸出。(數學函式,字串函式) UDAF(使用者定義聚集函式 User- Defined Aggregation Funcation):接收多個輸入資料行,併產生一個輸出資料行。(count,max)

JVM記憶體引數優化讓效能飛起來

JVM堆記憶體引數優化,讓效能飛起來 堆記憶體是Java程序的重要組成部分,幾乎所有與應用相關的記憶體空間都和堆有關。現在主要介紹與堆記憶體相關的引數設定,這些引數對Java虛擬機器中非常重要的,也是對程式效能有著重要的影響。讓你徹底脫離OOM記憶體溢位等等帶來

阿里試題FileInputStream 在使用完以後不關閉流想二次使用可以怎麼操作

FileInputStream 中有一個方法是open 方法呼叫的是本地的開啟檔案的方法,fileinputStream 就是通過這個方法來開啟檔案的,所以如果要重寫讀取這個檔案,不重新建立物件,那麼只要呼叫這個方法就可以了。 /** * Opens the specifie

【轉載】試題“你能不能談談java GC是在什麼時候對什麼東西做了什麼事情?”

面試題目:  地球人都知道,Java有個東西叫垃圾收集器,它讓建立的物件不需要像c/cpp那樣delete、free掉,你能不能談談: GC是在什麼時候,對什麼東西,做了什麼事情?   以上算是三個問題,下面逐一分析: 問題一回答:什麼時候? 1.系統空閒的時候。

11. 微軟試題輸入一個單向連結串列輸出該連結串列中倒數第k個結點。連結串列的倒數第0個結點為連結串列的尾指標

題目:輸入一個單向連結串列,輸出該連結串列中倒數第k個結點。連結串列的倒數第0個結點為連結串列的尾指標。 分析: 單鏈表只能向後遍歷,不能向前遍歷,尾指標好找,倒數第K個不能從尾指標向前找。 倒的不好找,正的好找,我們只需要知道連結串列的總長度,就可以知道正數第幾個節點(

試題C++有了malloc/free為什麼還需要new、delete?

1、面試寶典面試題(P81):C++有了malloc/free,為什麼還需要new、delete? malloc與free是C、C++語言的標準庫函式,new/delete是C++的運算子。他們都用於申請動態記憶體和釋放記憶體。 對於非內部資料型別的物件而言,只用mall

試題“你能不能談談java GC是在什麼時候對什麼東西做了什麼事情?”

地球人都知道,Java有個東西叫垃圾收集器,它讓建立的物件不需要像c/cpp那樣delete、free掉,你能不能談談,GC是在什麼時候,對什麼東西,做了什麼事情?一.回答:什麼時候?1.系統空閒的時候。    分析:這種回答大約佔30%,遇到的話一般我就會準備轉向別的話題,譬如演算法、譬如SSH看看能否發掘

一道試題請寫sql查詢出成績小於60的同學的姓名和平均分並按平均分排序

給出如下3張表,stu表、sc表和course表: /* Navicat MySQL Data Transfer Source Server         : db_fightLandlor Source Server Version : 50520 Source Ho

go語言試題輸入一段英文字串找出重複出現次數最多的字母

package main import ( "bufio" "os" "fmt" "strings" ) func main() { reader := bufio.NewReader(os.Stdin) str, err := reader.

試題實現兩個數的和不能用“+”“-”

這道題目和之前leetcode中的二進位制加法很相似。由於無法使用運算子,我們可以改用對位的操作。 如果不考慮進位的話:1+1=0,1+0=1,0+1=1,0+0=0,這剛好是異或計算^。 對於進位,正好是按位與&,左移一位之後的結果 在將兩者進行異或,之後再計算進