JVM 系列文章的第一篇。敬請期待後續。java
某年某月某日 上午,線上發生故障,通過排查,發現某核心服務 Dubbo 接口超時。git
查看該服務監控指標,發現該服務 FullGC 次數過於頻繁,簡直要上天了。那也難怪接口會超時了。github
那麼爲啥 FullGC 次數太多會形成接口超時呢?算法
由於 GC 停頓。 FullGC 時會產生GC停頓,也叫 stop the world。簡稱 STW ,是指在執行垃圾收集算法時,用戶線程都被掛起。這也不難理解爲啥 頻繁 FullGC 會引發服務超時了。jvm
那麼爲何會引發頻繁FullGC 呢?spa
回答這個問題以前,先了解下,有哪些狀況會觸發 Full GC ?.net
產生 FullGC 的基本緣由就上面三種。線程
故障服務就是建立不少對象,沒法回收,致使內存不足,而後 GC 回收不了時,就會引發頻繁 FullGC 了。對象
根據內存不足建立對象會引發 FullGC 的原理,寫了一個 Demo ,觀察GC 狀況。blog
代碼以下:
代碼很簡單,就是讓上次建立的對象能夠被回收,而後繼續建立對象,而後連接到根結點,使其不會被回收。demo 地址
使用啓動參數 -Xms512m -Xmx512m 設置堆內存大小。
啓動 Demo ,而後發起請求,觀察GC 狀況。
首先,使用命令 jps -l 查看進程ID
而後使用 jstat 命令查看GC信息 (jstat 命令詳解):
上圖能夠看到 正在不停的進行 Full GC.
上圖能夠看出,老年代,以及元數據區 內存空間已滿,這也是 不停 Full GC 的緣由。
再看我發出的請求:
過去這麼久,依然沒有結果。
使用 jstack 命令查看 線程狀態,發現 用戶線程已經被掛起。
不難看出,頻繁的 FullGC 已經影響到了應用的正常運行。
瞭解 JVM 仍是頗有必要的。CURD 不以爲什麼,問題來臨時就能夠so easy 了。