謹以此文獻給自學路上的兄弟
起因
這個測試工具的開發已有一段時間了,由於數據量過大,寫入數據較慢,導致工具執行耗時較長,所以再次優化了實現方案,進行二階段的程序開發。
經優化后,2000 條數據寫入,耗時4秒,個人感覺,快了很多了。
於是,想批量執行下,看下耗時多長。
結果10分鍾、20分鍾、1 個小時過去了...
程序一直在寫入數據,等的我這個藍瘦呀,尋思去泡杯茶吧。
結果,接完水回來,尼瑪報錯了,如下圖所示:
心里過程
雖然,作為一個測試喵,編碼能力與純開發相比,根本不是一個層次的。
當然,也可以通過求助開發同事解決,但這並不是退縮、逃避解決問題的理由。
這個報錯,我也是第一次遇到,對於一個不了解內存問題的測試來說,無疑是艱難的,結果各種搜。
最后,定位到是內存溢出導致的。
說實話,這個報錯卡了我近1.5天,我幾次想找同事解決,但我還是忍住了,還是想嘗試自己去解決。
常見的幾種內存溢出
- Java heap space
- GC overhead limit exceeded
- PermGen space
- Metaspace
嘗試過程
小編經驗有限,目前只遇到過第1、2種內存溢出問題。
下面來分享下,我排查問題的思路及過程。
網上大多數的博客和文章,寫的都是修改運行內存,我都試了一下,根本無效,廢棄方案如下:
黔驢技窮的我,突然想到之前性能測試,看到過開發通過JDK自帶工具jvisualvm,進行GC調優,結果還真的用上了。
如何操作
找到JDK安裝目錄 bin 下的 jvisualvm.exe,雙擊打開,如下圖所示。
運行你要監控的程序,雙擊左側運行程序,工具中會顯示程序的運行情況,只保留內存,其他不選,如下圖所示。
內存溢出,所以我們暫時只關注內存就可以了,內存會顯示運行時堆內數據的變化,如對象實例等。
接着是內心等待,查看監控內存情況,結果看到最大內存瞬間增長好幾倍,如下圖所示。
最大內存瞬間暴漲好幾倍,而且程序同時拋出如下異常。
問題定位出來了,接下來就是復現查找問題了。
將運行參數調整-Xmx216m,再次運行程序,同步驟 1、2,點擊,堆 dump, 進入監控界面,點擊切換至類選項卡如下圖所示。
結果終於被我找到這小子了,原來是它搞的鬼,創建了9314個char數組對象。
雙擊這個類名,找到問題如下圖所。
找到問題后,接下來就是優化程序的事了。
解決方案
經過以上的排查,找到了問題的原因,是因為寫數據時超過允許最大行數導致的溢出,最后采取分段寫入,完美解決了這個問題。
雖然解決了內存溢出問題,但程序的執行依然很慢,后來又找到了大數據的寫入數據方法,經過程序的再次優化,260W數據全部寫完僅需54秒,真的是 VERY NICE!
以上就是我排查問題的整個過程,當然這個案例的代碼是為了模擬內存溢出寫的一段程序,非業務代碼,僅供參考的入門案例。
寫在最后
jvisualvm、 jprofile 真的是一個內存優化、排查問題的一個好工具,可以說是寫程序必備神器。
關於內存溢出問題的文章很多,對我而言,能用上的真的是少之又少,作為一個測試喵並不敢造次和評價,有興趣的同學可以去買本書去深入學習了解。
這里要特別感謝強哥的幫助,每次都能給我很多的思路和靈感,讓我受益良多。
強哥
之前北京同事,多年經驗高級JAVA開發工程師
參考文章
解決項目中java heap space的問題[1]
記一次解決OutOfMemoryError: Java heap space詳細過程與解決思路[2]
參考資料
[1] 解決項目中java heap space的問題: https://blog.csdn.net/smh0310/article/details/90664598
[2] 記一次解決OutOfMemoryError: Java heap space詳細過程與解決思路: https://blog.csdn.net/lyflyyvip/article/details/82288719