SUN JDK+Tomcat 5.5.20運(yùn)行服務(wù)的時(shí)候遇到問題,服務(wù)器跑幾天后就會(huì)掛掉,并報(bào)java.lang.OutOfMemoryError: PermGen space異常。
發(fā)現(xiàn)很多人把問題歸因于: spring,hibernate,tomcat,因?yàn)樗麄儎?dòng)態(tài)產(chǎn)生類,導(dǎo)致JVM中的permanent heap溢出 。然后解決方法眾說紛紜,有人說升級(jí) tomcat版本到最新甚至干脆不用tomcat。還有人懷疑spring的問題,在spring論壇上討論很激烈,因?yàn)閟pring在AOP時(shí)使用CBLIB會(huì)動(dòng)態(tài)產(chǎn)生很多類。
但問題是為什么這些王牌的開源會(huì)出現(xiàn)同一個(gè)問題呢,那么是不是更基礎(chǔ)的原因呢?tomcat在Q&A很隱晦的回答了這一點(diǎn),我們知道這個(gè)問題,但這個(gè)問題是由一個(gè)更基礎(chǔ)的問題產(chǎn)生。
于是有人對(duì)更基礎(chǔ)的JVM做了檢查,發(fā)現(xiàn)了問題的關(guān)鍵。原來SUN 的JVM把內(nèi)存分了不同的區(qū),其中一個(gè)就是permenter區(qū)用來存放用得非常多的類和類描述。本來SUN設(shè)計(jì)的時(shí)候認(rèn)為這個(gè)區(qū)域在JVM啟動(dòng)的時(shí)候就固定了,但他沒有想到現(xiàn)在動(dòng)態(tài)會(huì)用得這么廣泛。而且這個(gè)區(qū)域有特殊的垃圾收回機(jī)制,現(xiàn)在的問題是動(dòng)態(tài)加載類到這個(gè)區(qū)域后,gc根本沒辦法回收!
2003年的時(shí)候就有一個(gè)bug報(bào)告給sun,但是到現(xiàn)在,這個(gè)bug還沒有close!有人在這個(gè)bug加了句評(píng)語(yǔ):“A bug this critical is open since 2003? Absolutely shameful.” 我覺得SUN在這個(gè)BUG上確實(shí)有些丟臉。
對(duì)這個(gè)bug最徹底的解決辦法就是不要用SUN的JDK,而改用BEA的 JRokit.
打不過,還逃不過嗎? 有眾多的選擇,這就是開源的好。 :)