關於 "Unloading class sun.reflect.GeneratedSerial...

謹以此文記念一次悲劇的經歷,並總結從中獲得的經驗教訓。


最近,因爲項目須要,要在一個Tomcat上部署多個Web應用。考慮到Tomcat的最大堆大小爲128MB,因此我對Tomcat的JVM參數作如下調整,並輸出GC日誌。參數以下 html

-Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=512M -Xloggc:D:/TomcatGc.log

然而在應用啓動完成以後,在控制檯不斷輸出如下「奇怪信息 linux

[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor339]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor336]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor341]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor342]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor340]

查看輸出的GC日誌,發現JVM從394.237S到2040.453s之間都在頻繁地進行FullGC 算法




要知道JVM頻繁地進行FullGC確定不是什麼好事情。因而就經過Google去搜索是什麼緣由致使那些「奇怪信息」的輸出。 數組


網上有許多回答都說是因爲堆空間不夠,JVM正嘗試回收一些無用的對象。我在StackOverFlow上也發起相關的提問,給的回答也是這個 因此就信覺得真,開始加大堆大小,調整參數以下: 框架

-Xms512m -Xmx1024m -XX:PermSize=128M  -XX:MaxPermSize=512M -Xloggc:D:/TomcatGc.log

在應用啓動完成以後,一開始並無當即出現那些「奇怪信息」。可是在大約過了10分鐘左右。控制檯又不斷輸出上述「奇怪信息」。 spa

通過一番折騰以後,我終於否決了堆空間不夠致使那些」奇怪信息「輸出的回答了,這哪裏是這個緣由致使的,簡直就是坑爹。 .net


那究竟是什麼緣由致使的呢?回想起本身之前學過的JVM的知識。JVM運行時數據區域有分爲方法區和堆。方法區(也叫永久代)用於存儲類型信息、常量和靜態變量等。堆空間用於存儲對象和數組等。根據GC算法,堆空間又分爲新生代和老年代。在新生代中會觸發MinorGC(也稱GC),老年代會觸發MajorGC(也稱Full GC).關於更多的信息能夠參考我以前的文章 hibernate


然而不少人都忽略了方法區也能夠存在GC操做。此次悲劇的產生也是因爲本身開始忽略這點致使的。要知道方法區的GC主要回收兩部份內容:廢棄常量和無用的類(注意這裏的類和對象是兩個不一樣的概念)。 代理


判斷一個類是不是無用的類須要知足下面3個條件:
1.該類全部的實例都已經被回收,也就是Java堆中不存在該類的任何實例
2.加載該類的ClassLoader已經被回收

3.該類對應的Java.lang.Class對象沒有在任何地方被引用,沒法在任何地方經過反射訪問該類的方法
日誌


JVM能夠對知足上述3個條件的無用類進行回收,這裏說的僅僅是「能夠」,而不是和對象同樣,不使用了就必然會回收。是否對類進行回收,JVM提供了-Xnoclassgc參數進行控制。因而,我在Tomcat的Jvm參數里加上 -Xnoclassgc並限制 -XX:PermSize=128M   -XX:MaxPermSize=128M.從新啓動Tomcat後,上述「奇怪信息」就不在出現了,並拋出了OutOfMemory  PermGen space 異常。關於 OutOfMemory  PermGen space 異常。這裏也有一個很是有趣的討論,你們能夠看下。

總結:

    在大量使用發射、動態代理、cglib等框架好比Spring、hibernate等,都須要虛擬機具有類卸載的功能,以保證方法區不會溢出。若是限制類卸載功能及限制 PermSize大小,相信方法區很快就會溢出。因此那些「奇怪信息」也屬於正常的輸出。另外也能夠經過調大 PermSize的值已保證有足夠的空間來裝載這些類信息,這樣,「奇怪信息」就可能不會輸出了。

1.區分JVM的中永久代、新生代和老年代的概念。記住Full GC和GC都發生在堆中。

2.致使頻繁的Full GC的緣由是堆空間大小不夠,可是奇怪的信息輸出毫不是堆空間不足產生。

3.折騰一天算是浪費時間,可是從中也學到和鞏固很多知識也算是塞翁失馬。

-----------------------------------全文完----------------------------------
相關文章
相關標籤/搜索