日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

java.lang.OutOfMemoryError的兩種解決辦法

 老張的菜地 2019-09-03

         不管是現(xiàn)在還是將來,每個(gè)java開發(fā)人員都會(huì)遇到j(luò)ava.lang.OutOfMemoryError錯(cuò)誤。盡管開發(fā)人員也會(huì)因?yàn)樵斐蓛?nèi)存的泄漏而出現(xiàn)OutOfMemoryError錯(cuò)誤,但這個(gè)問題更多是由于系統(tǒng)的限制引起的,而不是開發(fā)人員的錯(cuò)。我發(fā)現(xiàn)關(guān)于引起這個(gè)錯(cuò)誤的原因和解決辦法盡管很平常很基礎(chǔ),但在很多年輕的開發(fā)者仍然對(duì)他們一無所知。這篇文章我們將探索什么是java.lang.OutOfMemoryError錯(cuò)誤,為什么這個(gè)錯(cuò)誤會(huì)出現(xiàn)在我們的程序中,不同OutOfMemoryError錯(cuò)誤的區(qū)別以及如何修正這個(gè)錯(cuò)誤。這篇文章只是純粹的提供關(guān)于java.lang.OutOfMemoryError基礎(chǔ)知識(shí),而不會(huì)對(duì)它進(jìn)行詳細(xì)討論。

      什么是java.lang.OutOfMemoryError?

       Java.lang.OutOfMemoryError是java.lang.VirtualMachineError的子類。在堆耗盡內(nèi)存的時(shí)候,jvm會(huì)拋出Java.lang.OutOfMemoryError。這個(gè)錯(cuò)誤大多數(shù)出現(xiàn)在當(dāng)你去創(chuàng)建一個(gè)對(duì)象,但是在堆中卻不能為這個(gè)對(duì)象分配足夠多空間的時(shí)候。而且在java api文檔中,并沒有對(duì)這個(gè)錯(cuò)誤做大量的解釋。

     OutOfMemoryError的類型

      在java中有兩種主要的OutOfMemoryError類型:                                                                            
(1) Java.lang.OutOfMemoryError: Java heap space
(2) Java.lang.OutOfMemoryError: PermGen space
盡管它們都發(fā)生在內(nèi)存耗盡的情況下,但它們之間是相當(dāng)不同的,它們的解決辦法也是各不一樣。

        兩種OutOfMemoryError之間的區(qū)別

           如果你熟悉堆的歷代版本和垃圾收集器的工作原理,并且知道到新的,老的和永久的堆空間,那么你將會(huì)非常容易解決OutOfMemoryError錯(cuò)誤。永久的堆空間用于存儲(chǔ)jvm相關(guān)類,方法和其他實(shí)體的字符串池和各種元數(shù)據(jù)。因?yàn)榇蠖鄶?shù)jvm默認(rèn)的Perm Space(永久的堆空間)的大小是64M左右,所以如果你的工程里有太多的類或者數(shù)量巨大的字符串的話,那么很容易就會(huì)耗盡內(nèi)存。需要指出的一點(diǎn)是它并不依賴” Xmx”(譯者注: -Xms  指JVM初始分配的堆內(nèi)存,-Xmx  指 JVM最大允許分配的堆內(nèi)存)的值,所以不管你的堆空間多么大,一樣會(huì)耗盡Perm Space。好的辦法是你可以根據(jù)工程的需要通過JVM的選項(xiàng)指定永久堆空間的大小,即'-XX:PermSize' and  '-XX:MaxPermSize'。
一個(gè)很小的事情是要記得在指定堆的Perm Space(永久的堆空間)的大小的時(shí)候需要用”=”來分離參數(shù)名稱和值,但在指定堆得最大值的時(shí)候是不需要“=”的,正如下面的例子一樣:
Export  JVM_ARGS='-Xmx1024m -XX:MaxPermSize=256m'
           'java.lang.OutOfMemoryError: PermGen'的另一個(gè)原因是類加載器造成的內(nèi)存泄漏,它經(jīng)常出現(xiàn)在web服務(wù)器和應(yīng)用服務(wù)器中,例如tomcat, webshere, glassfish or weblogic。在應(yīng)用服務(wù)器中,不同的類加載器用于加載不同的web應(yīng)用,以便在相同的服務(wù)器上部署和取消部署一個(gè)應(yīng)用而且不會(huì)影響其他的應(yīng)用程序。但是當(dāng)取消部署的時(shí)候,如果容器持有類加載器已經(jīng)加載的類的引用,那么這個(gè)類和相關(guān)的類就不會(huì)被垃圾回收器回收。如果你部署和取消部署你的應(yīng)用很多次,那么很快PermGen space就會(huì)被填滿。'java.lang.OutOfMemoryError: PermGen”在我們的上一個(gè)項(xiàng)目中的tomcat里已經(jīng)被發(fā)現(xiàn)多次,但是這個(gè)問題的解決辦法實(shí)在是令人捉摸不透。因?yàn)槟闶紫戎滥膫€(gè)類引起了內(nèi)存泄露,然后你才能修正它。這個(gè)問題的另一個(gè)原因是應(yīng)用啟動(dòng)了一些線程,但是當(dāng)取消部署的時(shí)候,這些線程并沒有退出。
              這只是一些臭名昭著的類加載器造成內(nèi)存泄露的例子,任何人在編寫加載類和取消加載類的代碼的時(shí)候都要非常小心以避免這些問題。你也可以使用visualgc 監(jiān)測(cè)PermGen space,這個(gè)工具會(huì)展示PermGen space的使用情況圖表,你可以看到PermGen space是怎樣并且何時(shí)增長(zhǎng)的。我建議在得出任何結(jié)論之前先使用這個(gè)工具。
關(guān)于'java.lang.OutOfMemoryError: PermGen'的原因,我們發(fā)現(xiàn)另一個(gè)更加無知但有趣的是對(duì)于 JVM 的參數(shù) '-Xnoclassgc'的介紹。這個(gè)選項(xiàng)用于避免加載和取消加載一些已經(jīng)沒有被引用的類,這樣可以避免因?yàn)轭l繁的加載和取消加載而影響性能。但是在J2EE環(huán)境中使用這個(gè)選項(xiàng)是很危險(xiǎn)的,因?yàn)樵S多框架,例如struts,spring等使用反射機(jī)制去創(chuàng)建類,并且會(huì)頻繁的部署和取消部署,如果上一個(gè)引用沒有被清除,那么很快PermGen space就會(huì)被耗盡。這個(gè)例子也說明一些時(shí)候錯(cuò)誤的JVM參數(shù)或配置也會(huì)引起OutOfMemoryError錯(cuò)誤。
            所以結(jié)論是不要在J2EE環(huán)境中使用'-Xnoclassgc',尤其是在應(yīng)用服務(wù)器上。

         Tomcat解決Java.lang.OutOfMemoryError: PermGen space錯(cuò)誤的辦法

         對(duì)于tomcat6.0及其以上版本,提供了內(nèi)存泄漏偵測(cè)的能力。它可以通過web應(yīng)用視圖展示一些偵測(cè)到的平常的內(nèi)存泄漏問題,例如web應(yīng)用中的ThreadLocal內(nèi)存泄漏,JDBC驅(qū)動(dòng)注冊(cè),RMI ,LogFactory和線程等。你可以在htp://wiki.apache.org/tomcat/MemoryLeakProtection 查看具體的細(xì)節(jié),也可以通過tomcat提供的管理程序偵測(cè)內(nèi)存泄漏。你如果想在web應(yīng)用程序上檢驗(yàn)內(nèi)存泄漏問題,使用tomcat是個(gè)不錯(cuò)的主意。

          如何解決java.lang.OutOfMemoryError: Java heap space

         1) 解決OutOfMemoryError的簡(jiǎn)單方法是通過指定JVM參數(shù)'-Xmx512M'來指定最大的堆空間,這種方法效果立竿見影。當(dāng)我使用eclipse,maven,ant編譯工程遇到OutOfMemoryError的時(shí)候,我更喜歡使用這種辦法。這里有一個(gè)增加JVM堆空間的例子,建議為你的程序增加堆空間的時(shí)候最好保持-Xmx 相比-Xms 是1:1或者1:1.5的比例。
例: export JVM_ARGS='-Xms1024m -Xmx1024m'
           2) 第二種解決辦法是很困難的,當(dāng)你擁有的內(nèi)存并不多或者在你增加了堆內(nèi)存但是你依然會(huì)遇到OutOfMemoryError錯(cuò)誤時(shí),這種情況下你可能想要去分析你的應(yīng)用程序并且尋找內(nèi)存泄漏的原因。你可以使用Eclipse Memory Analyzer來檢查heap dump,或者可以使用Netbeans, Jprobe等這些分析工具。這種方法比較困難,需要花費(fèi)大量時(shí)間去分析找出內(nèi)存泄漏的原因。

           如何解決java.lang.OutOfMemoryError: PermGen space

           正如前面講到的一樣,java.lang.OutOfMemoryError: PermGen space發(fā)生在永久堆內(nèi)存耗盡的情況下。要修正這個(gè)情況,需要通過JVM選項(xiàng)   '-XX:MaxPermSize'來增加Perm space的最大大小,也可以通過'-XX:PermSize'指定Perm space的初始大小。同時(shí)設(shè)置這兩個(gè)值,可以避免在Perm Space重置大小的時(shí)候發(fā)生完全的垃圾回收。下面是設(shè)置初始化和最大值的例子:
export JVM_ARGS='-XX:PermSize=64M -XX:MaxPermSize=256m'
           有時(shí)候java.lang.OutOfMemoryError是莫名其妙的,這種情況下分析是最終的解決辦法。盡管你有增加堆內(nèi)存的空間的自由,但還是建議遵循內(nèi)存管理實(shí)踐,在編碼的時(shí)候?qū)]用的引用設(shè)置為null。以上我對(duì)OutOfMemoryError的全部理解,我也在其他的一些帖子中努力寫出java關(guān)于查找內(nèi)存泄漏的文章和使用分析器的方法。希望你也能分享解決OutOfMemoryError的觀點(diǎn)。
           注意: 對(duì)于tomcat6.0及其以上版本,提供了內(nèi)存泄漏偵測(cè)的能力。它可以通過web應(yīng)用視圖展示一些偵測(cè)到的平常的內(nèi)存泄漏問題,例如web應(yīng)用中的ThreadLocal內(nèi)存泄漏,JDBC驅(qū)動(dòng)注冊(cè),RMI ,LogFactory和線程等。你可以在htp://wiki.apache.org/tomcat/MemoryLeakProtection 查看具體的細(xì)節(jié),也可以通過tomcat提供的管理程序偵測(cè)內(nèi)存泄漏。你如果想在web應(yīng)用程序上檢驗(yàn)內(nèi)存泄漏問題并且找到PermGen space造成的OutOfMemoryError的原因,使用tomcat是個(gè)不錯(cuò)的主意。

          調(diào)查修正OutOfMemoryError的工具

             Java.lang.OutOfMemoryError是一種你需要做大量的調(diào)查才能找到根本原因的錯(cuò)誤。沒有對(duì)內(nèi)存工具的足夠了解,你不可能做某些事情,例如查找哪個(gè)對(duì)象在占用內(nèi)存,占用了多少內(nèi)存,以及找到可怕的內(nèi)存泄漏等等。這里我列出一些免費(fèi)的工具可以幫助你分析堆的使用情況,以及造成OutOfMemoryError的罪魁禍?zhǔn)住?br>

             1)Visualgc

              Visualgc代表Visual Garbage Collection Monitoring Tool 。你可以將它用于你的hostspot JVM。Visualgc最大的優(yōu)勢(shì)是能生動(dòng)展現(xiàn)出各種關(guān)鍵數(shù)據(jù),包括類加載器,垃圾回收和JVM編譯器性能數(shù)據(jù)。
JVM被識(shí)別是通過虛擬機(jī)的標(biāo)識(shí)符,稱為: vmid。你可以在這了解更多關(guān)于visualgc和vmid的東西。

              2)Jmap

             Jmap是來自JDK6的命令行工具,它允許你將堆的內(nèi)存轉(zhuǎn)儲(chǔ)信息保存到文件中。而且很方便使用,如:jmap -dump:format=b,file=heapdump 6054
這里指定的內(nèi)存轉(zhuǎn)儲(chǔ)的文件名稱是heapdump,6054是java進(jìn)程的PID。你可以通過'ps -ef”或者windows任務(wù)管理器或者“jps”工具(Java Virtual Machine Process Status Tool)查找PID.

              3) Jhat

             Jhat之前被稱為hat (heap analyzer tool),現(xiàn)在它是JDK6的一部分,你可
以使用Jhat去分析'jmap'生成的文件。Jhat也是一個(gè)命令行工具,你可以在windows命令行這樣使用它,如: jhat -J-Xmx256m heapdump 
這里它會(huì)分析“heapdump”文件中的內(nèi)存問題。當(dāng)你啟動(dòng)Jhat后,它就會(huì)讀取內(nèi)存轉(zhuǎn)儲(chǔ)文件,并且在http端口監(jiān)聽。只需要通過瀏覽器進(jìn)入端口,你就可以開始分析內(nèi)存轉(zhuǎn)儲(chǔ)文件中的對(duì)象。Jhat默認(rèn)監(jiān)聽7000端口。

              4)Eclipse memory analyzer

              Eclipse memory analyzer (MAT)是來自eclipse基金會(huì)的一個(gè)分析java堆內(nèi)存的工具。它能幫助你找到類加載器的泄漏,內(nèi)存泄漏和減少內(nèi)存消耗。你可以使用MAT分析內(nèi)存轉(zhuǎn)儲(chǔ)中數(shù)以百萬計(jì)的對(duì)象,也可以幫助你提取懷疑的內(nèi)存泄漏。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多