打破PermGen神话
在我的最新文章中,我解釋了可能導(dǎo)致java.lang.OutOfMemoryError:PermGen空間崩潰的原因 。 現(xiàn)在該討論該問(wèn)題的可能解決方案了。 或者,更確切地說(shuō),是關(guān)于互聯(lián)網(wǎng)對(duì)可能解決方案的建議。 不幸的是,我只能說(shuō),我對(duì)MythBusters的內(nèi)心Jamie Hyneman進(jìn)行了不同的“專(zhuān)家意見(jiàn)”喚醒。
我搜索了有關(guān)解決java.lang.OutOfMemoryError:PermGen空間崩潰的方法的當(dāng)前常識(shí),并瀏覽了幾十個(gè)頁(yè)面,這些頁(yè)面似乎更適合Google結(jié)果。 幸運(yùn)的是,大多數(shù)建議已被提煉為備受推崇的StackOverflow的主題 。 如您所見(jiàn),該主題非常受歡迎,并獲得了一些頗受好評(píng)的答案。 但是具有諷刺意味的是,整個(gè)主題包含的零解決方案我可以向我推薦。 好吧,除了“查找內(nèi)存泄漏的原因”外,這當(dāng)然是絕對(duì)正確的,但對(duì)回答“如何解決內(nèi)存泄漏”的問(wèn)題不是很有幫助。 讓我們回顧一下SO頁(yè)面上提出的建議。
使用-XX:MaxPermSize = XXXM
導(dǎo)致java.lang.OutOfMemoryError的原因有兩個(gè):PermGen空間錯(cuò)誤。
一種是應(yīng)用程序服務(wù)器和/或應(yīng)用程序確實(shí)確實(shí)使用了太多的類(lèi),以致它們不適合默認(rèn)大小的永久代。 絕對(duì)有可能,但實(shí)際上并非如此。 在這種情況下,增加永久代的大小確實(shí)可以節(jié)省一天。 如果您唯一的問(wèn)題是如何在太多的小房子里放太多家具,那就買(mǎi)更大的房子!
但是,如果您的愛(ài)心媽媽每周都會(huì)給您寄去新家具呢? 您可能無(wú)法一遍又一遍地搬到更大的房子。 正如我在上面提到的上一篇文章中所描述的,這正是內(nèi)存泄漏以及類(lèi)加載器泄漏的情況。 在此讓我清楚:永久代大小的增加不會(huì)使您免于類(lèi)加載器泄漏。 它只能推遲。 并更難預(yù)測(cè)服務(wù)器將淘汰多少次重新部署。
-XX:+ CMSPermGenSweepingEnabled
關(guān)于StackOverflow的最流行的答案是將這些選項(xiàng)添加到服務(wù)器的命令行中。 而且,他們說(shuō):“也可以添加-XX:+ UseConcMarkSweepGC。 只是要確定”。 這些JVM標(biāo)志的第一個(gè)問(wèn)題是沒(méi)有關(guān)于它們真正作用的解釋。 無(wú)論是在SO答案中(我都不喜歡告訴您在沒(méi)有理由的情況下要做某事的答案),還是在整個(gè)Internet中都是如此。
確實(shí),除了此頁(yè)面之外,我找不到有關(guān)這些選項(xiàng)的任何文檔。 但是,實(shí)際上,這甚至沒(méi)有關(guān)系。 絕不會(huì)對(duì)垃圾收集器選項(xiàng)進(jìn)行任何修補(bǔ),以防在班機(jī)泄漏時(shí)發(fā)生。 因?yàn)榘凑斩x, 內(nèi)存泄漏是GC不足的情況。 如果從服務(wù)器的類(lèi)加載器中的某個(gè)地方到應(yīng)用程序的對(duì)象或類(lèi)之間存在有效的實(shí)時(shí)硬引用,則GC將永遠(yuǎn)不會(huì)將其視為垃圾,也永遠(yuǎn)不會(huì)對(duì)其進(jìn)行回收。 當(dāng)然,所有這些JVM標(biāo)志看起來(lái)都很聰明和神奇。 在某些情況下,可能確實(shí)需要使用它們。 但是它們肯定不夠 ,不能解決您的永久代泄漏。
使用JRockit
下一個(gè)建議是切換到JRockit JVM。 理由是,由于JRockit沒(méi)有永久代,因此無(wú)法用完它。 當(dāng)然,這是一個(gè)有趣的主張。 不幸的是,它也不能解決我們的問(wèn)題。
此“解決方案”的唯一結(jié)果將是獲取java.lang.OutOfMemoryError:Java堆空間,而不是java.lang.OutOfMemoryError:PermGen空間。 在沒(méi)有單獨(dú)生成類(lèi)定義的情況下,JRockit為它們使用通常的Java堆空間。 而且,只要泄漏的根本原因沒(méi)有得到解決,只要有足夠的時(shí)間,這些類(lèi)定義甚至可以填滿最大的堆。
重新啟動(dòng)服務(wù)器
假裝問(wèn)題已解決的另一種方法是不時(shí)重新啟動(dòng)應(yīng)用程序服務(wù)器。 例如,無(wú)需重新部署應(yīng)用程序,只需重新啟動(dòng)整個(gè)服務(wù)器即可。 但是,當(dāng)您第一次看到部署了多個(gè)應(yīng)用程序的應(yīng)用程序服務(wù)器時(shí),您會(huì)知道在生產(chǎn)環(huán)境中幾乎不可能做到這一點(diǎn)。 這并不是真正的解決方案。 這是將您的頭藏在沙子里的一種方法。
使用Tomcat
實(shí)際上,這并不是以前的絕望之作-最近的Tomcat版本確實(shí)嘗試解決類(lèi)加載器泄漏。 自己看看他們的文檔 。 如果您可以將Tomcat用作目標(biāo)服務(wù)器,并且如果您的泄漏是Tomcat可以成功應(yīng)對(duì)的泄漏之一,那么也許,也許您很幸運(yùn),問(wèn)題就為您解決了。
在此處使用<您最喜歡的探查器工具>
也可能是可行的解決方案。 但是,再加上幾個(gè)IF 。 首先,您應(yīng)該能夠在受影響的環(huán)境中使用該探查器。 正如我之前在其他文章中提到的那樣, 探查器施加的開(kāi)銷(xiāo)水平在(生產(chǎn))環(huán)境中可能是不可接受的。 其次,您必須知道如何使用探查器提取所需的信息并確定泄漏的位置。 而我10多年的經(jīng)驗(yàn)表明,這種情況很少發(fā)生。
結(jié)論
到目前為止,我們還沒(méi)有看到j(luò)ava.lang.OutOfMemoryError:PermGen空間錯(cuò)誤的任何確定解決方案。 在某些情況下,有些方法是可行的。 但是,令我震驚的是,大多數(shù)建議都完全無(wú)效 ! 您可能會(huì)浪費(fèi)數(shù)天或數(shù)周的時(shí)間來(lái)嘗試它們,甚至沒(méi)有開(kāi)始解決真正的問(wèn)題:找到流氓的根本原因,以防泄漏!
幸運(yùn)的是,從1.1版本開(kāi)始, Plumbr還發(fā)現(xiàn)了PermGen泄漏 。 它告訴您阻止類(lèi)加載器被釋放的根本原因,從而節(jié)省了尋找漏洞的時(shí)間。 因此,下一次,當(dāng)遇到j(luò)ava.lang.OutOfMemoryError:PermGen空間消息時(shí), 下載Plumbr并永久擺脫該問(wèn)題。
參考: Plumbr博客博客上來(lái)自我們JCG合作伙伴 Nikita Salnikov Tarnovski的 PermGen神話 。
翻譯自: https://www.javacodegeeks.com/2012/12/busting-permgen-myths.html
總結(jié)
以上是生活随笔為你收集整理的打破PermGen神话的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 用方面清理代码
- 下一篇: 农行债市宝1年期跟3年期的区别?