成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

關(guān)于JVM內(nèi)存溢出的原因分析及解決方案探討

xuexiangjys / 2179人閱讀

摘要:內(nèi)存溢出分配的內(nèi)存空間超過系統(tǒng)內(nèi)存。內(nèi)存泄漏的原因分析由大塊組成堆,棧,本地方法棧,程序計數(shù)器,方法區(qū)。內(nèi)存溢出的原因分析內(nèi)存溢出是由于沒被引用的對象垃圾過多造成沒有及時回收,造成的內(nèi)存溢出。小結(jié)棧內(nèi)存溢出程序所要求的棧深度過大導(dǎo)致。

前言:JVM中除了程序計數(shù)器,其他的區(qū)域都有可能會發(fā)生內(nèi)存溢出。
0.什么是內(nèi)存溢出

當(dāng)程序需要申請內(nèi)存的時候,由于沒有足夠的內(nèi)存,此時就會拋出OutOfMemoryError,這就是內(nèi)存溢出。

1.內(nèi)存泄漏和內(nèi)存溢出區(qū)別與聯(lián)系

內(nèi)存泄漏:系統(tǒng)分配的內(nèi)存沒有被回收。

內(nèi)存溢出:分配的內(nèi)存空間超過系統(tǒng)內(nèi)存。

2.內(nèi)存泄漏的原因分析

jvm由5大塊組成:堆,棧,本地方法棧,程序計數(shù)器,方法區(qū)。棧它的主要記錄方法的執(zhí)行和對象的引用。堆則存在真正的引用的對象。

內(nèi)存泄漏是由于使用不當(dāng),把一部分內(nèi)存“丟掉了”,導(dǎo)致這部分內(nèi)存不可用。

當(dāng)在堆中創(chuàng)建了對象,后來沒有使用這個對象了,又沒有把整個對象的相關(guān)引用設(shè)為null。此時垃圾收集器會認(rèn)為這個對象是需要的,就不會清理這部分內(nèi)存。這就會導(dǎo)致這部分內(nèi)存不可用。

所以內(nèi)存泄漏會導(dǎo)致可用的內(nèi)存減少,進而會導(dǎo)致內(nèi)存溢出。

3. JVM垃圾回收機制思想

就是從棧出發(fā)(root),遍歷對象的引用,在遍歷堆里面的引用對象,因為棧中的對象的引用執(zhí)行完畢就刪除,所以我們就可以通過棧中的對象的引用,查找到堆中沒有被指向的對象,這些對象即為不可到達對象,對其進行垃圾回收。

4.內(nèi)存溢出的原因分析

內(nèi)存溢出是由于沒被引用的對象(垃圾)過多造成JVM沒有及時回收,造成的內(nèi)存溢出。如果出現(xiàn)這種現(xiàn)象可行代碼排查:

是否App中的類中和引用變量過多使用了Static修飾 如public staitc Student s;在類中的屬性中使用
static修飾的最好只用基本類型或字符串。如public static int i = 0; //public static
String str;

是否App中使用了大量的遞歸或無限遞歸(遞歸中用到了大量的建新的對象)

是否App中使用了大量循環(huán)或死循環(huán)(循環(huán)中用到了大量的新建的對象)

檢查App中是否使用了向數(shù)據(jù)庫查詢所有記錄的方法。即一次性全部查詢的方法,如果數(shù)據(jù)量超過10萬多條了,就可能會造成內(nèi)存溢出。所以在查詢時應(yīng)采用“分頁查詢”。

檢查是否有數(shù)組,List,Map中存放的是對象的引用而不是對象,因為這些引用會讓對應(yīng)的對象不能被釋放。會大量存儲在內(nèi)存中。

檢查是否使用了“非字面量字符串進行+”的操作。因為String類的內(nèi)容是不可變的,每次運行"+"就會產(chǎn)生新的對象,如果過多會造成新String對象過多,從而導(dǎo)致JVM沒有及時回收而出現(xiàn)內(nèi)存溢出。

如:

String s1 = "My name";
String s2 = "is";
String s3 = "xiaomanong";
String str = s1 + s2 + s3 +.........;

這是會容易造成內(nèi)存溢出的

但是String str = "My name" + " is " + " xuwei" + " nice " + " to " + " meet you"; //但是這種就不會造成內(nèi)存溢出。因為這是”字面量字符串“,在運行"+"時就會在編譯期間運行好。不會按照J(rèn)VM來執(zhí)行的。

在使用String,StringBuffer,StringBuilder時,如果是字面量字符串進行"+"時,應(yīng)選用String性能更好;如果是String類進行"+"時,在不考慮線程安全時,應(yīng)選用StringBuilder性能更好。

5.常見的四種內(nèi)存溢出情況

堆溢出(OutOfMemoryError:java heap space)

持久代溢出(OutOfMemoryError: PermGen space)

棧溢出(StackOverflowError)

OutOfMemoryError:unable to create native thread

1)堆溢出:JVM Heap :java.lang.OutOfMemoryError: Java heap space

JVM在啟動的時候會自動設(shè)置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等選項可進行設(shè)置。Heap的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的時間是用于GC,且可用的Heap size 不足2%的時候?qū)伋龃水惓P畔ⅰ?/p>

解決方法 :手動設(shè)置JVM Heap(堆)的大小。

2)持久代溢出:PermGen space : java.lang.OutOfMemoryError: PermGen space

PermGen space的全稱是Permanent Generation space,是指內(nèi)存的永久保存區(qū)域。為什么會內(nèi)存溢出,這是由于這塊內(nèi)存主要是被JVM存放Class和Meta信息的,Class在被Load的時候被放入PermGen space區(qū)域,它和存放Instance的Heap區(qū)域不同,sun的 GC不會在主程序運行期對PermGen space進行清理,所以如果你的APP會載入很多CLASS的話,就很可能出現(xiàn)PermGen space溢出。一般發(fā)生在程序的啟動階段。

解決方法 : 通過-XX:PermSize和-XX:MaxPermSize設(shè)置永久代大小即可。

3)棧溢出: java.lang.StackOverflowError : Thread Stack space

棧溢出了,JVM依然是采用棧式的虛擬機,這個和C和Pascal都是一樣的。函數(shù)的調(diào)用過程都體現(xiàn)在堆棧和退棧上了。調(diào)用構(gòu)造函數(shù)的 “層”太多了,以致于把棧區(qū)溢出了。 通常來講,一般棧區(qū)遠遠小于堆區(qū)的,因為函數(shù)調(diào)用過程往往不會多于上千層,而即便每個函數(shù)調(diào)用需要 1K的空間(這個大約相當(dāng)于在一個C函數(shù)內(nèi)聲明了256個int類型的變量),那么棧區(qū)也不過是需要1MB的空間。通常棧的大小是1-2MB的。通俗一點講就是單線程的程序需要的內(nèi)存太大了。 通常遞歸也不要遞歸的層次過多,很容易溢出。

解決方法 :1:修改程序。2:通過 -Xss: 來設(shè)置每個線程的Stack大小即可。

4)OutOfMemoryError:unable to create native thread

OutOfMemoryError:unable to create native thread:字面意思是內(nèi)存溢出:無法創(chuàng)建新的線程。字面意思已經(jīng)很明顯了,出現(xiàn)這種情況的原因基本下面2點:

程序創(chuàng)建的線程數(shù)超過操作系統(tǒng)的限制。

JVM占用的內(nèi)存太多,導(dǎo)致創(chuàng)建線程的內(nèi)存空間太小。

我們都知道操作系統(tǒng)對每個進程的內(nèi)存是有限制的,我們啟動Jvm,相當(dāng)于啟動了一個進程,假如我們一個進程占用了4G的內(nèi)存,那么通過下面的公式計算出來的剩余內(nèi)存就是建立線程棧的時候可以用的內(nèi)存。 線程??偪捎脙?nèi)存=4G-(-Xmx的值)- (-XX:MaxPermSize的值)- 程序計數(shù)器占用的內(nèi)存 通過上面的公式我們可以看出,-Xmx 和 MaxPermSize的值越大,那么留給線程??捎玫目臻g就越小,在-Xss參數(shù)配置的棧容量不變的情況下,可以創(chuàng)建的線程數(shù)也就越小。因此如果是因為這種情況導(dǎo)致的unable to create native thread,

解決方法:1:增大進程所占用的總內(nèi)存。2:減少-Xmx或者-Xss來達到創(chuàng)建更多線程的目的。

5)小結(jié)

棧內(nèi)存溢出:程序所要求的棧深度過大導(dǎo)致。
堆內(nèi)存溢出: 分清 內(nèi)存泄露還是 內(nèi)存容量不足。泄露則看對象如何被 GC Root 引用。不足則通過 調(diào)大 -Xms,-Xmx參數(shù)。
持久帶內(nèi)存溢出:Class對象未被釋放,Class對象占用信息過多,有過多的Class對象。
無法創(chuàng)建本地線程:總?cè)萘坎蛔?,堆?nèi)存,非堆內(nèi)存設(shè)置過大,會導(dǎo)致能給線程的內(nèi)存不足。

補充:阿里巴巴內(nèi)存溢出面試題

下面哪種情況會導(dǎo)致持久區(qū)jvm堆內(nèi)存溢出():

A. 循環(huán)上萬次的字符串處理

B. 在一段代碼內(nèi)申請上百M甚至上G的內(nèi)存

C. 使用CGLib技術(shù)直接操作字節(jié)碼運行,生成大量的動態(tài)類

D. 不斷創(chuàng)建對象

解答:AC

解析:AC是持久帶,B直接內(nèi)存也就是堆外內(nèi)存,D堆內(nèi)存。

參考書籍:

《深入理解Java虛擬機》 (第二版) 周志明 著;

溫馨提示: 如果你喜歡本文,并且想要學(xué)習(xí)更多干貨內(nèi)容,可以關(guān)注一下我的公眾號《Java技術(shù)zhai》; 
不定期的技術(shù)干貨內(nèi)容分享,帶你重新理解架構(gòu)的魅力!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76057.html

相關(guān)文章

  • Java深入-框架技巧

    摘要:從使用到原理學(xué)習(xí)線程池關(guān)于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實現(xiàn)在軟件開發(fā)中,分散于應(yīng)用中多出的功能被稱為橫切關(guān)注點如事務(wù)安全緩存等。 Java 程序媛手把手教你設(shè)計模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經(jīng)風(fēng)雨慢慢變老,回首走過的點點滴滴,依然清楚的記得當(dāng)初愛情萌芽的模樣…… Java 進階面試問題列表 -...

    chengtao1633 評論0 收藏0
  • 學(xué)習(xí)JVM是如何從入門到放棄

    摘要:而字節(jié)碼運行在之上,所以不用關(guān)心字節(jié)碼是在哪個操作系統(tǒng)編譯的,只要符合規(guī)范,那么,這個字節(jié)碼文件就是可運行的。好處防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼安全性角度特別說明類加載器在成功加載某個類之后,會把得到的類的實例緩存起來。 前言 只有光頭才能變強 JVM在準(zhǔn)備面試的時候就有看了,一直沒時間寫筆記?,F(xiàn)在到了一家公司實習(xí),閑的時候就寫寫,刷刷JVM博客,刷刷電子書。 學(xué)習(xí)JVM的目的也很簡單...

    Joyven 評論0 收藏0
  • JVM爆炸幾種姿勢自救方法

    摘要:方法區(qū)溢出在的方法區(qū)中,它主要存放了類的信息,常量,靜態(tài)變量等。運行結(jié)果簡單解決思路一般來說此類問題多出現(xiàn)在存在遞歸的地方,要從代碼里重新審視遞歸未結(jié)束的原因,若遞歸的方法沒問題可以根據(jù)實際情況調(diào)整參數(shù)的大小。 前言 如今不管是在面試還是在我們的工作中,OOM總是不斷的出現(xiàn)在我們的視野中,所以我們有必要去了解一下導(dǎo)致OOM的原因以及一些基本的調(diào)整方法,大家可以通過下面的事例來了解一下什...

    hyuan 評論0 收藏0

發(fā)表評論

0條評論

xuexiangjys

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<