中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java虛擬機線上問題排查的2個基本操作,你知不知道?

發布時間:2020-07-26 11:54:15 來源:網絡 閱讀:361 作者:架構師追風 欄目:編程語言

前言

對于后端程序員,特別是 Java 程序員來講,排查線上問題是不可避免的。各種 CPU 飚高,內存溢出,頻繁 GC 等等,這些都是令人頭疼的問題。樓主同樣也遇到過這些問題,那么,遇到這些問題該如何解決呢?

首先,出現問題,肯定要先定位問題所在,然后分析問題原因,再然后解決問題,最后進行總結,防止下次再次出現。

今天的文章,就如我們的題目一樣,講的是基本操作,也就是一些排查線上問題的基本方法。為什么這么說呢?因為線上問題千奇百怪,就算是身經百戰的專家也會遇到棘手的問題,因此不可能在一篇文章里說完,還有一個最重要的原因,當然就是樓主的水平不到位。

但不到位歸不到位,任何經驗都是值得記錄的,因此,樓主有必要將這些問題記錄一下。

還有,本文的排查環境是 Linux.

Java虛擬機線上問題排查的2個基本操作,你知不知道?

CPU 飚高

線上 CPU 飚高問題大家應該都遇到過,那么如何定位問題呢?

思路:首先找到 CPU 飚高的那個 Java 進程,因為你的服務器會有多個 JVM 進程。然后找到那個進程中的 “問題線程”,最后根據線程堆棧信息找到問題代碼。最后對代碼進行排查。

如何操作呢?

  1. 通過 top 命令找到 CPU 消耗最高的進程,并記住進程 ID。

  2. 再次通過 top -Hp [進程 ID] 找到 CPU 消耗最高的線程 ID,并記住線程 ID.

  3. 通過 JDK 提供的 jstack 工具 dump 線程堆棧信息到指定文件中。具體命令:jstack -l [進程 ID] >jstack.log。

  4. 由于剛剛的線程 ID 是十進制的,而堆棧信息中的線程 ID 是16進制的,因此我們需要將10進制的轉換成16進制的,并用這個線程 ID 在堆棧中查找。使用 printf "%x\n" [十進制數字] ,可以將10進制轉換成16進制。

  5. 通過剛剛轉換的16進制數字從堆棧信息里找到對應的線程堆棧。就可以從該堆棧中看出端倪。

從樓主的經驗來看,一般是某個業務死循環沒有出口,這種情況可以根據業務進行修復。還有 C2 編譯器執行編譯時也會搶占 CPU,什么是 C2編譯器呢?當 Java 某一段代碼執行次數超過10000次(默認)后,就會將該段代碼從解釋執行改為編譯執行,也就是編譯成機器碼以提高速度。而這個 C2編譯器就是做這個的。如何解決呢?項目上線后,可以先通過壓測工具進行預熱,這樣,等用戶真正訪問的時候,C2編譯器就不會干擾應用程序了。如果是 GC 線程導致的,那么極有可能是 Full GC ,那么就要進行 GC 的優化。

Java虛擬機線上問題排查的2個基本操作,你知不知道?

內存問題排查

說完了 CPU 的問題排查,再說說內存的排查,通常,內存的問題就是 GC 的問題,因為 Java 的內存由 GC 管理。有2種情況,一種是內存溢出了,一種是內存沒有溢出,但 GC 不健康。

內存溢出的情況可以通過加上 -XX:+HeapDumpOnOutOfMemoryError 參數,該參數作用是:在程序內存溢出時輸出 dump 文件。

有了 dump 文件,就可以通過 dump 分析工具進行分析了,比如常用的MAT,Jprofile,jvisualvm 等工具都可以分析,這些工具都能夠看出到底是哪里溢出,哪里創建了大量的對象等等信息。

第二種情況就比較復雜了。GC 的健康問題。

通常一個健康的 GC 是什么狀態呢?根據樓主的經驗,YGC 5秒一次左右,每次不超過50毫秒,FGC 最好沒有,CMS GC 一天一次左右。

而 GC 的優化有2個維度,一是頻率,二是時長。

我們看YGC,首先看頻率,如果 YGC 超過5秒一次,甚至更長,說明系統內存過大,應該縮小容量,如果頻率很高,說明 Eden 區過小,可以將 Eden 區增大,但整個新生代的容量應該在堆的 30% - 40%之間,eden,from 和 to 的比例應該在 8:1:1左右,這個比例可根據對象晉升的大小進行調整。

如果 YGC 時間過長呢?YGC 有2個過程,一個是掃描,一個是復制,通常掃描速度很快,復制速度相比而言要慢一些,如果每次都有大量對象要復制,就會將 STW 時間延長,還有一個情況就是 StringTable ,這個數據結構中存儲著 String.intern 方法返回的常連池的引用,YGC 每次都會掃描這個數據結構(HashTable),如果這個數據結構很大,且沒有經過 FGC,那么也會拉長 STW 時長,還有一種情況就是操作系統的虛擬內存,當 GC 時正巧操作系統正在交換內存,也會拉長 STW 時長。

再來看看FGC,實際上,FGC 我們只能優化頻率,無法優化時長,因為這個時長無法控制。如何優化頻率呢?

首先,FGC 的原因有幾個,

1 是 Old 區內存不夠,

2 是元數據區內存不夠,

3 是 System.gc(),

4 是 jmap 或者 jcmd,

5 是CMS Promotion failed 或者 concurrent mode failure,

6 JVM 基于悲觀策略認為這次 YGC 后 Old 區無法容納晉升的對象,因此取消 YGC,提前 FGC。

通常優化的點是 Old 區內存不夠導致 FGC。如果 FGC 后還有大量對象,說明 Old 區過小,應該擴大 Old 區,如果 FGC 后效果很好,說明 Old 區存在了大量短命的對象,優化的點應該是讓這些對象在新生代就被 YGC 掉,通常的做法是增大新生代,如果有大而短命的對象,通過參數設置對象的大小,不要讓這些對象進入 Old 區,還需要檢查晉升年齡是否過小。如果 YGC 后,有大量對象因為無法進入 Survivor 區從而提前晉升,這時應該增大 Survivor 區,但不宜太大。

上面說的都是優化的思路,我們也需要一些工具知道 GC 的狀況。

JDK 提供了很多的工具,比如 jmap ,jcmd 等,oracle 官方推薦使用 jcmd 代替 jmap,因為 jcmd 確實能代替 jmap 很多功能。jmap 可以打印對象的分布信息,可以 dump 文件,注意,jmap 和 jcmd dump 文件的時候會觸發 FGC ,使用的時候注意場景。

還有一個比較常用的工具是 jstat,該工具可以查看GC 的詳細信息,比如eden ,from,to,old 等區域的內存使用情況。

還有一個工具是 jinfo,該工具可以查看當前 jvm 使用了哪些參數,并且也可以在不停機的情況下修改參數。

包括我們上面說的一些分析 dump 文件的可視化工具,MAT,Jprofile,jvisualvm 等,這些工具可以分析 jmap dump 下來的文件,看看哪個對象使用的內存較多,通常是能夠查出問題的。
歡迎大家關注我的公種浩【程序員追風】,文章都會在里面更新,整理的資料也會放在里面。

還有很重要的一點就是,線上環境一定要帶上 GC 日志!!!

Java虛擬機線上問題排查的2個基本操作,你知不知道?

總結

基于文章的標題,我們這個是基本操作,故障排查是說不完的話題,每個故障涉及的知識也都很多,因此,我們在學習了基本的排查之后,還需要學習更多事故排查技術,比如排查 IO,網絡,TCP 連接等等。樓主將在后面的文章中將這些基本操作都記錄下來。

最后

歡迎大家一起交流,喜歡文章記得點個贊喲,感謝支持!


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

启东市| 建昌县| 寻乌县| 石景山区| 寿阳县| 南皮县| 尼勒克县| 福泉市| 青海省| 水城县| 闸北区| 城步| 分宜县| 南和县| 璧山县| 壶关县| 蒙山县| 榆树市| 孝感市| 麟游县| 昆山市| 西宁市| 呼玛县| 中牟县| 兖州市| 清涧县| 伊金霍洛旗| 娄底市| 双流县| 思茅市| 武宣县| 当涂县| 乌什县| 苏尼特右旗| 绩溪县| 五常市| 古交市| 花垣县| 津南区| 西充县| 双辽市|