
在線上運(yùn)行的程序,有一天突然前端響應(yīng)緩慢,但是后臺日志依舊還在正常輸出。針對這種情況,本篇博客主要是進(jìn)行問題解決的過程說明。
軟件 | 版本
|
Centos | 6.4 |
JDK | 1.6 |
proxool | 0.9.0RC3 |
jstat -gcutil 13062 5000
從上圖可以看出,現(xiàn)在項(xiàng)目是處于頻繁GC的狀態(tài),內(nèi)存基本都被占滿了。
jmap -histo:live 13062 | head -20
從上圖可以看到,目前是數(shù)據(jù)庫相關(guān)的類占用了比較大的空間。其中有proxool,這個(gè)時(shí)候猜測是因?yàn)閜roxool的問題導(dǎo)致的。
jmap -dump:format=b,file=heap-dump.bin 13062
將第4步導(dǎo)出的堆棧信息,使用MAT工具打開,打開之后,進(jìn)行分析,分析結(jié)果如下:
從圖中,可以知道,F(xiàn)inalizer占用了最大的空間,達(dá)到了2.9GB。
之后,我們使用以下命令將該進(jìn)程的堆棧信息dump下來,如下:
jstack 13062 > 13062 _error.log
并搜索Finalizer字眼,結(jié)果如下:
這個(gè)就是比較著名的??proxool?
??內(nèi)存泄露問題,在??JVM?
??回收??WrappedConnection?
??對象時(shí),由于代理類重寫了??finalize?
??方法,??WrappedConnection?
??方法被丟進(jìn)引用隊(duì)列等待??finalizer?
??線程執(zhí)行??finalize?
??方法,??finalize?
??本身沒有額外的實(shí)現(xiàn),但是代理類在執(zhí)行該方法之前會做一個(gè)??isClose?
??的判斷,而??jdbc oracle?
??的實(shí)現(xiàn)類則使用了??synchronize?
??修飾了??isClose?
??,導(dǎo)致業(yè)務(wù)邏輯從池里拿出來該連接使用的時(shí)候會與??finalize?
??線程競爭該鎖,一旦業(yè)務(wù)邏輯處于繁忙狀態(tài)則??finalizer?
?線程執(zhí)行的頻率大大減小,此時(shí)在隊(duì)列中的引用依然存在,對象仍然會在堆中存活。
既然知道了原因,那么覆寫??org.logicalcobwebs.proxool.WrappedConnection?
?類,添加以下代碼:
然后重新編譯提交到項(xiàng)目中,并重啟。
升級補(bǔ)丁之后,重啟項(xiàng)目。到了第二天,再將堆棧信息dump下來查看,已經(jīng)沒有Finalizer的內(nèi)存占用了。問題得到解決。
本篇博文主要是記錄此次解決過程中使用的各種命令,熟悉使用可以解決很多問題。
??解決proxool連接oracle內(nèi)存溢出的問題????壓測調(diào)優(yōu)之遇到的proxool問題??
如果我的文章對大家產(chǎn)生了幫忙,可以在文章底部點(diǎn)個(gè)贊或者收藏;如果有好的討論,可以留言;
如果想繼續(xù)查看我以后的文章,可以點(diǎn)擊關(guān)注可以掃描以下二維碼,關(guān)注我的公眾號:楓夜之求索閣,查看我最新的分享!