www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > > 架構(gòu)師社區(qū)
[導(dǎo)讀]這個面試題是一個朋友在面試的時候碰到的,什么時候會拋出OutOfMemery異常呢?初看好像挺簡單的,其實(shí)深究起來考察的是對整個JVM的了解,而且這個問題從網(wǎng)上可以翻到一些亂七八糟的答案,其實(shí)在總結(jié)下來基本上4個場景可以概括下來。

這個面試題是一個朋友在面試的時候碰到的,什么時候會拋出OutOfMemery異常呢?初看好像挺簡單的,其實(shí)深究起來考察的是對整個JVM的了解,而且這個問題從網(wǎng)上可以翻到一些亂七八糟的答案,其實(shí)在總結(jié)下來基本上4個場景可以概括下來。

堆內(nèi)存溢出

堆內(nèi)存溢出太常見,大部分人都應(yīng)該能想得到這一點(diǎn),堆內(nèi)存用來存儲對象實(shí)例,我們只要不停的創(chuàng)建對象,并且保證GC Roots和對象之間有可達(dá)路徑避免垃圾回收,那么在對象數(shù)量超過最大堆的大小限制后很快就能出現(xiàn)這個異常。

寫一段代碼測試一下,設(shè)置堆內(nèi)存大小2M。

面試官:哪些場景會產(chǎn)生OOM?怎么解決?
public class HeapOOM { public static void main(String[]?args) {
????????Listlist?= new ArrayList<>(); while (true)?{
????????????list.add(new HeapOOM());
????????}
????}
}

運(yùn)行代碼,很快能看見OOM異常出現(xiàn),這里的提示是Java heap space堆內(nèi)存溢出。

面試官:哪些場景會產(chǎn)生OOM?怎么解決?

一般的排查方式可以通過設(shè)置-XX: +HeapDumpOnOutOfMemoryError在發(fā)生異常時dump出當(dāng)前的內(nèi)存轉(zhuǎn)儲快照來分析,分析可以使用Eclipse Memory Analyzer(MAT)來分析,獨(dú)立文件可以在官網(wǎng)下載。

另外如果使用的是IDEA的話,可以使用商業(yè)版JProfiler或者開源版本的JVM-Profiler,此外IDEA2018版本之后內(nèi)置了分析工具,包括Flame Graph(火焰圖)和Call Tree(調(diào)用樹)功能。

面試官:哪些場景會產(chǎn)生OOM?怎么解決? 面試官:哪些場景會產(chǎn)生OOM?怎么解決? 火焰圖

方法區(qū)(運(yùn)行時常量池)和元空間溢出

方法區(qū)和堆一樣,是線程共享的區(qū)域,包含Class文件信息、運(yùn)行時常量池、常量池,運(yùn)行時常量池和常量池的主要區(qū)別是具備動態(tài)性,也就是不一定非要是在Class文件中的常量池中的內(nèi)容才能進(jìn)入運(yùn)行時常量池,運(yùn)行期間也可以可以將新的常量放入池中,比如String的intern()方法。

我們寫一段代碼驗(yàn)證一下String.intern(),同時我們設(shè)置-XX:MetaspaceSize=50m -XX:MaxMetaspaceSize=50m 元空間大小。由于我使用的是1.8版本的JDK,而1.8版本之前方法區(qū)存在于永久代(PermGen),1.8之后取消了永久代的概念,轉(zhuǎn)為元空間(Metaspace),如果是之前版本可以設(shè)置PermSize MaxPermSize永久代的大小。

private static String?str?= "test"; public static void main(String[]?args) {
????????Listlist?= new ArrayList<>(); while (true){
????????????String?str2?=?str?+?str;
????????????str?=?str2;
????????????list.add(str.intern());
????????}
}

運(yùn)行代碼,會發(fā)現(xiàn)代碼報(bào)錯。

面試官:哪些場景會產(chǎn)生OOM?怎么解決?

再次修改配置,去除元空間限制,修改堆內(nèi)存大小-Xms20m -Xmx20m,可以看見堆內(nèi)存報(bào)錯。

面試官:哪些場景會產(chǎn)生OOM?怎么解決?

這是為什么呢?intern()本身是一個native方法,它的作用是:如果字符串常量池中已經(jīng)包含一個等 于此String對象的字符串,則返回代表池中這個字符串的String對象;否則,將此String對象包含的字符串添加到常量池中,并且返回String對象的引用。

而在1.7版本之后,字符串常量池已經(jīng)轉(zhuǎn)移到堆區(qū),所以會報(bào)出堆內(nèi)存溢出的錯誤,如果1.7之前版本的話會看見PermGen space的報(bào)錯。

直接內(nèi)存溢出

直接內(nèi)存并不是虛擬機(jī)運(yùn)行時數(shù)據(jù)區(qū)域的一部分,并且不受堆內(nèi)存的限制,但是受到機(jī)器內(nèi)存大小的限制。常見的比如在NIO中可以使用native函數(shù)直接分配堆外內(nèi)存就容易導(dǎo)致OOM的問題。

直接內(nèi)存大小可以通過-XX:MaxDirectMemorySize指定,如果不指定,則默認(rèn)與Java 堆最大值-Xmx一樣。

由直接內(nèi)存導(dǎo)致的內(nèi)存溢出,一個明顯的特征是在Dump文件中不會看見明顯的異常,如果發(fā)現(xiàn)OOM之后Dump文件很小,而程序中又直接或間接使用了NIO,那就可以考慮檢查一下是不是這方面的原因。

棧內(nèi)存溢出

棧是線程私有,它的生命周期和線程相同。每個方法在執(zhí)行的同時都會創(chuàng)建一個棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,方法調(diào)用的過程就是棧幀入棧和出棧的過程。

在java虛擬機(jī)規(guī)范中,對虛擬機(jī)棧定義了兩種異常:

  1. 如果線程請求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverflowError異常
  2. 如果虛擬機(jī)??梢詣討B(tài)擴(kuò)展,并且擴(kuò)展時無法申請到足夠的內(nèi)存,拋出OutOfMemoryError異常

先寫一段代碼測試一下,設(shè)置-Xss160k,-Xss代表每個線程的棧內(nèi)存大小

public class StackOOM { private int length?= 1; public void stackTest() {
????????System.out.println("stack?lenght=" +?length);
????????length++;
????????stackTest();
????} public static void main(String[]?args) {
????????StackOOM?test?= new StackOOM();
????????test.stackTest();
????}
}

測試發(fā)現(xiàn),單線程下無論怎么設(shè)置參數(shù)都是StackOverflow異常。

面試官:哪些場景會產(chǎn)生OOM?怎么解決?

嘗試把代碼修改為多線程,調(diào)整-Xss2m,因?yàn)闉槊總€線程分配的內(nèi)存越大,??臻g可容納的線程數(shù)量越少,越容易產(chǎn)生內(nèi)存溢出。反之,如果內(nèi)存不夠的情況,可以調(diào)小該參數(shù)來達(dá)到支撐更多線程的目的。

public class StackOOM { private void dontStop() { while (true)?{
????????}
????} public void stackLeakByThread() { while (true)?{ new Thread(()?->?dontStop()).start();
????????}
????} public static void main(String[]?args) throws Throwable {
????????StackOOM?stackOOM?= new StackOOM();
????????stackOOM.stackLeakByThread();
????}
}


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計(jì)中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計(jì)工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉