一、問題是怎么發(fā)現(xiàn)的
最近有個新系統(tǒng)開發(fā)完成后要上線,由于系統(tǒng)調(diào)用量很大,所以先對核心接口進(jìn)行了一次壓力測試,由于核心接口中基本上只有純內(nèi)存運算,所以預(yù)估核心接口的壓測QPS能夠達(dá)到上千。
壓測容器配置:4C8G
先從10個并發(fā)開始進(jìn)行發(fā)壓,結(jié)果cpu一下就飆升到了100%,但是核心接口的qps才200左右。于是觀察jvm的垃圾回收發(fā)現(xiàn)younggc很頻繁,但是fullGC數(shù)量為零。
二、排查問題的詳細(xì)過程
由于剛一開始壓測,容器cpu就飆升到了100%,所以需要先定位cpu使用率問題,找出使用cpu最高的幾個進(jìn)程。可以通過top命令查找進(jìn)程ID,發(fā)現(xiàn)正是壓測的Java應(yīng)用進(jìn)程ID;然后在定位該金晨曦cpu使用率最高的線程,可以通過top -p 進(jìn)程ID -H 命令顯示該進(jìn)程下的線程使用cpu信息。
top
top -p 進(jìn)程ID -H
圖片中PID列則為十進(jìn)制顯示的線程ID,然后轉(zhuǎn)換為16進(jìn)制;在通過jstack 系統(tǒng)進(jìn)程ID | grep 16進(jìn)制線程ID 命令找到對應(yīng)的線程信息如下,也就是該線程占用了一半左右的cpu。
jstack 系統(tǒng)進(jìn)程ID | grep 16進(jìn)制線程ID
此時定位到了Finalizer線程,但是這個線程又有什么作用呢?
原來這個線程會不停的循環(huán)等待java.lang.ref.Finalizer.ReferenceQueue中的新增對象。一旦Finalizer線程發(fā)現(xiàn)隊列中出現(xiàn)了新的對象,它會彈出該對象,調(diào)用它的finalize()方法,將該引用從Finalizer類中移除,因此下次GC再執(zhí)行的時候,這個Finalizer實例以及它引用的那個對象就可以被垃圾回收掉了。如果這個線程一直在不停的工作,說明Finalizer的隊列中有許多等待GC的垃圾對象。此時可以通過另一個命令來查看等待回收的垃圾對象有哪些。
jmap -finalizerinfo 進(jìn)程ID
Count Class description
-------------------------------------------------------
32221 com.jd.price.deep.exact.entity.coupons.DeepExactCouponVo$$EnhancerByCGLIB$$200e6ee6
14908 com.jd.pricedoor.compute.promotion.MultiplePromotion$$EnhancerByCGLIB$$a59933de
11982 java.util.zip.Deflater
1 java.net.SocksSocketImpl
通過上述結(jié)果可以發(fā)現(xiàn)有好多的業(yè)務(wù)對象,通過類名可以看到這些對象都是通過CGLIB動態(tài)代理創(chuàng)建的,而且這些動態(tài)代理類都默認(rèn)實現(xiàn)了finalize方法,導(dǎo)致這些對象在進(jìn)行垃圾回收時必須先要執(zhí)行finalize方法,所以都積壓到了finalizer的隊列中。
三、如何解決問題
通過上述排查過程發(fā)現(xiàn),是由于大量的業(yè)務(wù)對象通過CGLIB創(chuàng)建了動態(tài)代理類,而這些代理都是系統(tǒng)處理請求時創(chuàng)建的臨時對象,請求完成后,這些臨時對象就需要被垃圾回收掉,從而導(dǎo)致Finalizer線程執(zhí)行頻繁搶占了cpu資源。
針對以上分析結(jié)果所以有了如下幾種解決方案:
1.不要使用CGLIB來給那些需要頻繁進(jìn)行垃圾回收的對象創(chuàng)建動態(tài)代理,可以手動創(chuàng)建靜態(tài)代理類。
2.對象復(fù)用,盡量減少臨時對象的產(chǎn)生。
作者:京東零售 曹志飛文章來源:http://www.zghlxwxcb.cn/news/detail-620808.html
來源:京東云開發(fā)者社區(qū)文章來源地址http://www.zghlxwxcb.cn/news/detail-620808.html
到了這里,關(guān)于CGLIB動態(tài)代理對象GC問題排查的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!