日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

内存泄漏java例子_一次线上Java应用内存泄漏分析实例

發布時間:2023/12/15 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存泄漏java例子_一次线上Java应用内存泄漏分析实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

由于JVM的內存管理采用GC垃圾自動回收機制,這使得Java程序員在編程的時候確實可以從內存管理中釋放出來,但這也引發了另外一個大問題,一旦Java應用出現內存泄漏的時候,常常讓人措手不及,陷入無從下手的尷尬境地,我們總不能一句話重啟吧(苦笑)。

內存問題可能是大多數Java程序員心中都曾有過的傷,因為太容易遇見了。

下面這篇文章是我去年寫在個人微信公眾號上的,今天早上回頭再看心中不免有些噓噓感慨,于是決定重新整理把它發到簡書上來,以下為正文:

前2天負責的一個線上系統在早上9點20分接到大量用戶反饋系統很卡,頁面無響應。我聯系運維及時查看后臺服務器,發現WAS(Websphere) server bin目錄下生成了javacore 和heapdump,這個消息讓我整個人都不好了,項目推廣關鍵時期居然來這么一出,可謂多事之秋,搞事情啊!

好吧,既然程序運行時遇到了坑,那我們就先來找到這個坑,再把坑填好(圍笑)。

簡單介紹下,線上應用運行在power linux OS平臺之上,web容器為IBM WebSphere ,JDK ?ibm j9vm 64 位。

首先開始通過ibm ha456.jar 分析線上dump 文件

上圖Heap usage,堆內存已使用約3.7G,且41.95%的內存都被rootobject 和它的引用吃掉了,接下來我再查看rootobject,如下圖:

內存主要是被2個LinkedHashMap吃掉了,于是仔細查找項目源碼中會用到LinkedHashMap的地方,無果。

接下來再來看一下這些LinkedHashMap當中都包含什么對象,看看它們會指向哪些東西呢,如下圖:

這里發現有一個org.xhtmlrender.resource.ImageResource類,且點開所有節點LinkedHashMap 都有此類的實例及強引用,如下圖顯示第一個root? LinkedHashMap 有178個此類實例

于是繼續分析下ImageResource類節點,如下圖:

此對象節點只有一個parentes node,且這個parentes node 對象就是LinkedHashMap

接著我查看項目源碼,發現 org.xhtmlrender.resource.ImageResource類屬于如下圖:

Maven 引用如下:

分析項目代碼,上面3個jar包是用來將html文件轉成pdf文件,目前能推斷出的結論是此功能模塊耗用盡了jvm 堆內存,由此導致線上應用崩潰了。。。

仔細檢查這一功能塊區域的代碼發現不存在有大規模瞬時加載大量數據到內存中的潛在代碼,由此判斷不是瞬時某個交易功能導致,應該是此功能區域的某個方法執行時存在內存泄漏的可能。

線上應用架構是集群 F5部署,因此有另外一臺尚沒有生成javacore 的was服務做對比,于是在當晚非作業時間,kill -3 [pid]生成dump 文件進一步分析,發現這臺應用的堆內存也用到3.6G,只是還沒有到崩潰的臨界點而已,且都是被同樣的LinkedHashMap 吃掉大半以上。

內存泄漏點幾乎已確定在此處了,于是讓同事寫了一個客戶端測試小程序并發的對此功能區方法Action發起請求,以下為測試環境請求我自己本地服務JVM監控圖示:

1

上部左邊圖可看出垃圾回收活動越來越頻繁,上部右邊圖堆內存的已使用占比也在緩慢遞增,典型的內存有泄漏,GC每次回收都不完全,導致GC回收的復雜度越來越高,離out of memory?只是時間問題。

再對測試環境中的was服務器進行壓測,以進一步驗證此問題點,發現was體系內存的開銷更明顯,如下圖,看到內存呈現階梯式遞增

2

對比上面2圖,在客戶端測試程序壓力一定情況下,was服務器(1.6jdk)的表現比我本機還要糟糕,這可能是我本機Mac用的1.8 jdk JVM GC相對于1.6有優化吧。

服務端在運行4小時之后,內存耗盡,程序Over,且在was應用目錄下生成了javacore(這期間暫停過很多次客戶端壓力程序,但服務端JVM堆內存的占用一直是居高不下,無法回收)。

3

同樣使用ha456分析javacore,發現堆內存的耗用情況與生產幾乎一致,堆內存大部分都是耗用在LinkedHashMap和commons pool中

4

至此斷定問題一定是出在html轉pdf方法體中,查閱項目源碼及用到的開源jar包說明文檔,定位到出問題的關鍵代碼塊如下:

初步分析應該是ITextRenderObjctFactory中ObjctPool池的ITextRender對象資源不釋放導致的,對象池Factory關鍵配置如下:

查閱相關資料說明,我分析應該是ITextRende對象一直活躍在對象池pool中(pool默認配置:空閑對象可存活30分鐘),應用在白天作業期間對htmlToPdf方法的調用幾乎不會有空閑時間,所以render一直處于被外圍重復調用的情況,導致render持有的資源一直無法得到釋放的機會,進而使程序內存耗盡。

調研過其他項目組源碼也有類似實現的寫法,但是未出現內存耗盡的情況,對比源碼分析區別在于其他項目組render渲染html為pdf 時并未涉及到html文件中有可變圖片url引用的鏈入,而我們項目組每次html轉pdf 時存在可變路徑的圖片引用,導致render需要每次動態創建ImageResource類來動態加載外部圖片URL鏈接,而動態創建的ImageResource 實例并未能釋放。

因此對以上關鍵代碼進行優化如下:

第一個紅色箭頭修改部分改為document 由原來的url加載方式改為file

第二個紅色箭頭為新添加代碼,用于把ITextRender共享上下文Context內容重置,以便于單個render對象中的資源及時釋放;

同時對于ObjectPool池config配置優化如下,關鍵代碼:

修改參數說明如下:

1、空閑對象獲取策略修改為FIFO,先進先出,便于對象池中的對象公平共享使用,便于空閑未使用到的對象及時釋放

2、timeBetweenEvictionRunsMillis為每間隔5秒檢查一下是否存在空閑Idle對象

3、minEvictableIdleTimeMillis空閑對象存在1分鐘未被調用即銷毀

OK,優化之后,更新was服務,使用之前的客戶端測試程序發起壓力測試,將堆內存上限設定為1G,結果表現如下:

持續壓測2小時,內存耗用穩定在1G以內,當客戶端壓力撤去,3分鐘之后內存穩穩回收到200M左右,如下:

接下來穩定性測試6小時,持續壓測,壓力撤去之后,內存占用逐漸回歸到600M左右

更新線上應用程序不再出現問題,至此,總算把此問題解決。在這期間收集用于分析的javacore和dump文件約5G(包含測試環境was、生產環境was、本機tomcat)

以上從定為問題、找到原因、測試復現、解決問題到復測通過我斷斷續續用了2天時間,這2天放下了手頭一切工作上相對來說優先級沒有此問題高的事情,可能有的朋友會感覺我最近工作不走心了呢,其實不然,不會了(圍笑)。

軟件系統最常見的就是系統故障,人非圣賢孰能無過,程序員都是人,是人就會寫Bug,寫了Bug系統就會出問題,出了問題系統就可能宕機。即使你什么事都沒干正在家里陪老丈人喝酒,人家在微博上說,大家好,給大家介紹一下,這是我的女盆友。哐當,系統掛了,這特么能怪誰呢?真出了問題,慌,罵人,處罰都是后話,沒用的,重要的是解決問題,梳理流程,增加監控,減少損失,最后復盤問題才是牛批。

現在我們的項目正處于大力推廣前的關鍵時期,軟件將迎來最終用戶的快速增長,保持服務的穩定是重中之重。

前段時間看到Mac Talk公眾號池建強老師發的一篇原創文章,大意講的是我們每個人在臨大戰前應有靜氣,何意?就是你面臨壓力和挑戰的時候,一方面心跳加速血管收縮手心冒汗,但你感到的是興奮而不是焦慮,內心深處是安靜的,沉著的。

最后大家要是覺得本文還OK,對你的工作學習有所幫助的話請給點個贊?!筆芯

如果你對設計模式學習感興趣的話,請關注下我,因為我最近正在編寫一部《從零開始學設計模式》系列。

總結

以上是生活随笔為你收集整理的内存泄漏java例子_一次线上Java应用内存泄漏分析实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。