JAVA系列之JVM內存調優( 三 )


4、堆溢出(java.lang.OutOfMemoryError: Java heap space)堆溢出是常見也是最復雜的一種情況 。導致堆溢出可能的情況有:

  • 堆內存配置太小
  • 超出預期的訪問量:訪問量飆升
  • 超出預期的數據量:系統中是否存在一次性提取大量數據到內存的代碼
  • 內存泄漏
解決思路一般是:
一、堆dump文件獲取1、通過參數配置自動獲取dump文件(推薦)2、jmap -dump:format=b,file=filename.hprof pid二、MAT工具分析1、分析大對象、堆中存儲信息、可能存在的內存泄漏地方,便于定位問題位置
五、JVM監控常用的監控工具或命令有:jstack、jstat、jConsole、jvisualvm 。監控指標主要是各內存區域大小是否合理、fullGC頻率及耗時、youngGC耗時、線程數等 。
1、jstackjstack主要用于打印線程堆棧信息,幫助問題的定位 。一般配合top -Hp PID使用 。
通過top命令發現某個java服務占用1234%的CPU,如圖:
JAVA系列之JVM內存調優

文章插圖
通過top -Hp PID命令可以看到占用CPU比較高的線程,如圖:
JAVA系列之JVM內存調優

文章插圖
再次通過jstack PID>log.txt,輸出堆棧信息即可進行排查定位 。
2、jstatjstat命令是分析JVM運行狀況的常用命令 。
jstat -options-class 用于查看類加載情況的統計-compiler 用于查看HotSpot中即時編譯器編譯情況的統計-gc 用于查看JVM中堆的垃圾收集情況的統計-gccapacity 用于查看新生代、老生代及持久代的存儲容量情況-gcmetacapacity 顯示metaspace的大小-gcnew 用于查看新生代垃圾收集的情況-gcnewcapacity 用于查看新生代存儲容量的情況-gcold 用于查看老生代及持久代垃圾收集的情況-gcoldcapacity 用于查看老生代的容量-gcutil 顯示垃圾收集信息-gccause 顯示垃圾回收的相關信息(通-gcutil),同時顯示最后一次僅當前正在發生的垃圾收集的原因-printcompilation 輸出JIT編譯的方法信息
以jstat -gcutil為例:
[root@hadoop ~]# jstat -gcutil 3346 #顯示垃圾收集信息S0 S1 E O M CCS YGC YGCT FGC FGCT GCT52.97 0.00 42.10 13.92 97.39 98.02 8 0.020 0 0.000 0.020 
  • S0:年輕代中第一個survivor(幸存區)已使用的占當前容量百分比
  • S1:年輕代中第二個survivor(幸存區)已使用的占當前容量百分比
  • E:年輕代中Eden(伊甸園)已使用的占當前容量百分比
  • O:old代已使用的占當前容量百分比
  • M:元數據區已使用的占當前容量百分比
  • CCS:壓縮類空間已使用的占當前容量百分比
  • YGC :從應用程序啟動到采樣時年輕代中gc次數
  • YGCT :從應用程序啟動到采樣時年輕代中gc所用時間(s)
  • FGC :從應用程序啟動到采樣時old代(全gc)gc次數
  • FGCT :從應用程序啟動到采樣時old代(全gc)gc所用時間(s)
  • GCT:從應用程序啟動到采樣時gc用的總時間(s)
3、jConsoleJConsole是基于JMX的可視化監視、管理工具 。可以很方便的監視本地及遠程服務器的java進程的內存使用情況 。
3.1 被監控的程序運行時給虛擬機添加一些運行的參數
無需認證的遠程監控配置-Dcom.sun.management.jmxremote.port=60001//監控的端口號-Dcom.sun.management.jmxremote.authenticate=false//關閉認證-Dcom.sun.management.jmxremote.ssl=false-Djava.rmi.server.hostname=192.168.1.2
3.2 客戶端連接被監控程序找到 JDK 安裝路徑,打開bin文件夾 , 雙擊jconsole.exe,在已經打開的JConsole界面操作“連接->新建連接->選擇遠程進程->輸入遠程主機IP和端口號->點擊“連接
JAVA系列之JVM內存調優

文章插圖
JAVA系列之JVM內存調優

文章插圖
4、jvisualvmjvisualvm與jConsole連接方式一致,連接后界面如下:
JAVA系列之JVM內存調優

文章插圖

推薦閱讀