一、場景描述
上週開始系統在業務高峯期一直收到Full gc報警,監控顯示fgc頻繁,下圖是監控圖,左邊紅框是優化前效果,右邊是優化後,優化後fgc基本爲0
二、原因查找
1.查看gc日誌,發現old區fgc後大小沒有變化,如下圖:
2.去線上dump內存看是什麼對象,用memory analyzer分析,Retained Size竟然有2.4G,全是sun.awt.SunToolkit這個對象,其實到這一步已經可以確定是什麼問題了,只是自己對系統不是很熟悉,導致定位具體的問題代碼花了一些時間
三、原因分析
系統中有一個調用頻繁的接口會調用下面這個方法,目的是獲取圖片的寬高信息,但是Image這個對象用完不會自動釋放,需要手動調用 flush()方法;以前沒有調用這個方法,就導致一有請求就會有大對象進入old區,在業務高峯期old區一會就被打滿,所以一直進行fgc
public static Image getImage(String path) {
ImageIcon icon = new ImageIcon(path);
Image img = icon.getImage();
return img;
}
四、解決辦法
其實不管是用Image還是BufferedImage,讀取圖片的寬高不用把圖片全部加載到內存,在圖片的寬高信息其實是存儲在文件頭中的,只 要按不同的格式讀取文件的頭信息就可以拿到寬高信息
使用ImageReader代碼如下
Iterator readers = ImageIO.getImageReadersByFormatName(StringUtil.getFileSuffix(filePath));
ImageReader reader = (ImageReader)readers.next();
iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, true);
return Pair.of(reader.getWidth(0),reader.getHeight(0));
相關 [系統 full gc] 推薦:
系統頻繁Full gc問題分析及解決辦法
- - JavaRanger - 專注JAVA高性能程序開發、JVM、Mysql優化、算法觸發Full GC執行的情況
- - Web前端 - ITeye博客Full GC是否真的存在
- - Java譯站利用Arena Allocation避免HBase觸發Full GC
- Adam - 淘寶JAVA中間件團隊博客FULL GC有可能導致JVM暫停1分鐘以上嗎?
- - 高級語言虛擬機Tomcat的JreMemoryLeakPreventionListener監聽週期性頻繁執行full gc
- -Full Circle 51期發佈
- PT - Wow! Ubuntu初級分代GC
- - C++博客-首頁原創精華區GC 日誌分析
- - 碼蜂筆記遲到:Full Circle 中文版45期
- L - LinuxTOY遲到的社區雜誌 Full Circle 發佈 45 期中文版. 在這一期雜誌中,我們給您帶來了以下內容:. 決勝命令行 —— Conky 第二部分. How-To : Python 編程 , 虛擬化 : Debian Xen 以及 使用 m23 安裝 Ubuntu. Linux 實驗室 —— 多重啓動U盤.
jps -v xxx 顯示xxx進程的各項jvm參數
jstat -gcutil pid xxx
顯示xxx的堆分配情況以及垃圾回收次數時間
jstack 用法
Top 一下看一下cpu最高進程
Shift+h 查看線程
或者 top -p pid -H 查看該進程下的所有線程
找到最高的線程 vmid
jstack pid | grep -A 10 vmid(線程id的16進制其中字母要小寫)
jmap -histo:live pid 強制進行fullgc 查看實例數
ps -eLo pid,lwp,pcpu | grep 6124 |sort -rnk 3
Top -H -p 6124(進程id)
注意:
內存溢出的影響週期和JVM內存設置大小有關係,分配得越小,越容易出現。