謹以此文獻給自學路上的兄弟
起因
這個測試工具的開發已有一段時間了,由於資料量過大,寫入資料較慢,導致工具執行耗時較長,所以再次優化了實現方案,進行二階段的程式開發。
經優化後,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