解码Java.Lang.OutOfMemoryError:PermGen空间
Java開發人員最不了解的領域之一是垃圾收集。 Java開發人員認為JVM負責垃圾收集,因此他們不必擔心內存分配,釋放等問題。但是,隨著應用程序變得越來越復雜,垃圾收集也會變得越來越復雜,一旦性能變得復雜,性能便會受到影響。 因此,這將有利于Java開發人員了解垃圾回收的工作原理以及如何解決Java中的“內存不足”問題。 有2個非常常見的“內存不足”問題。 第一個是“堆大小”,第二個是“ PermGen空間”。
永久生成器和ClassLoader。
Java對象是Java類的實例。 每次創建新的Java對象時,JVM都會創建該對象的內部表示并將其存儲在堆中。 如果是第一次訪問該類,則必須由JVM加載它。 類加載是以下過程:查找相應的類文件,在磁盤上查找文件,加載文件并解析結構。 確保正確加載類是ClassLoaders的責任。java程序中的每個類都需要由同一ClassLoader加載。 ClassLoader是java.lang.ClassLoader類的實例。 現在,ClassLoader將Java類加載到Perm Space中。
JVM還創建了Java類的內部表示,這些類存儲在永久代中。 在垃圾回收期間,java對象和類都被視為對象,并且以相同的方式進行垃圾回收。 最初,java對象和類都存儲在堆空間中。
為了優化性能,創建了永久代,并在其中放置了類。類是我們JVM實現的一部分,我們不應該用數據結構填充Java堆。 永久代分配在堆大小之外。 永久世代包含以下類信息:
- 一類的方法。
- 類的名稱。
- 常量池信息。
- 與類關聯的對象數組和類型數組。
- JVM使用的內部對象。
- 編譯器用于優化的信息。
現在我們了解了什么是永久生成,讓我們看看是什么導致該區域的內存問題。
PermGen空間
當JVM需要加載新類的定義并且PermGen中沒有足夠的空間時,會發生“ Java.Lang.OutOfMemoryError:PermGen空間”。 服務器模式分配的默認PermGen空間為64 MB,客戶端模式分配的默認為32 MB。 發生PermGen Space問題的原因可能有兩個。
第一個原因可能是您的應用程序或服務器中的類太多,而現有的PermGen Space無法容納所有類。
-XX:MaxPermSize = XXXM
如果問題是由于類數量過多而導致PermGen空間不足,則可以通過添加–XX:MaxPermSize = XXm參數來增加PermGen空間。 這將增加可用于存儲類的空間,并且應-XX:MaxPermSize = 256m
-XX:+ CMSClassUnloadingEnabled
此參數指示使用CMS GC時是否啟用類卸載。 默認情況下,此選項設置為false,因此要啟用此功能,您需要在java options中顯式設置以下選項。
-XX:+ CMSClassUnloadingEnabled
如果啟用CMSClassUnloadingEnabled,則GC也會清除PermGen,并刪除不再使用的類。僅當使用以下選項啟用UseConcMarkSweepGC時,此選項才有效。
-XX:+ UseConcMarkSweepGC
-XX:+ CMSPermGenSweepingEnabled
此參數指示是否啟用了掃描電燙。 默認情況下,此參數是禁用的,因此需要顯式設置此參數以微調PermGen問題。 在Java 6中已刪除此選項,因此,如果使用Java 6或更高版本,則需要使用-XX:+ CMSClassUnloadingEnabled。 因此,為解決PermGen Space內存問題而添加的選項如下所示
-XX:MaxPermSize = 128m -XX:+ UseConcMarkSweepGC XX:+ CMSClassUnloadingEnabled
內存泄漏
第二個原因可能是內存泄漏。 裝入的類定義可能如何變得未使用。
通常在Java中,類是永遠的。 因此,一旦加載了類,即使該應用程序在服務器上停止,它們也會保留在內存中。 像cglib這樣的動態類生成庫使用了許多PermGen Space,因為它們動態創建了很多類。 大量使用Proxy類,這些類是在運行時綜合創建的。 當單個類定義可用于多個實例時,創建新的代理類很容易。
Spring和Hibernate通常代理某些類。 此類代理類由類加載器加載。 永遠不會丟棄生成的類定義,從而導致永久堆空間快速填充。
對于PermGen空間問題,您將需要確定泄漏原因并加以解決。 增加PermGen空間將無濟于事,只會延遲問題,因為在某些時候PermGen空間仍會被填滿。
如果您使用的是Tomcat并因內存泄漏而困擾,那么最新版本的Tomcat可以修復某些內存泄漏問題。
- http://wiki.apache.org/tomcat/MemoryLeakProtection
結論
一旦遇到PermGen Space問題,您將需要找出問題是由于您的應用程序正在加載大量類還是由于內存泄漏引起的。 如果是由于類數量過多,您可以進行微調以增加分配的PermGen空間,這將解決此問題。 如果問題是由于內存泄漏引起的,則需要找到泄漏的根本原因并加以解決。 某些框架的工作方式如cglib,Spring,Hibernate會創建大量動態生成的類,因此最好使用這些框架為項目分配更多的PermGen Space。
翻譯自: https://www.javacodegeeks.com/2013/12/decoding-java-lang-outofmemoryerror-permgen-space.html
總結
以上是生活随笔為你收集整理的解码Java.Lang.OutOfMemoryError:PermGen空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超星安卓版(超星安卓)
- 下一篇: 想要更快地使用AtomicLong? 等