1. 程式人生 > 其它 >Docker java jvm OOM記憶體溢位問題排查 診斷監控

Docker java jvm OOM記憶體溢位問題排查 診斷監控

Docker容器內監控
檢視docker執行狀態
docker stats cid

top 找到耗費關鍵資源的程序
ps -ef|grep java 通過PID找到和top命令輸出的PID

docker ps 找到進入的容器id
docker exec -it 1231sdf1323 /bin/sh 進入容器
jps 或 jps -l -m 找到java 程序pid

檢視容器重啟次數
docker inspect -f “{{ .RestartCount }}” container-id

檢視容器最後一次的啟動時間
docker inspect -f “{{ .State.StartedAt }}” container-id

docker 啟動命令增加 記憶體洩露時匯出heapdump檔案
-e ‘JAVA_OPTS=-server -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/heapdump.hprof’

jmap 記憶體分析
ps – ef | grep java 檢視PID
jmap -heap 6 可以用來檢視堆記憶體的使用詳情
jmap -histo:live 6 | more 檢視堆記憶體中的物件的數目,佔用記憶體(單位是byte),如果帶上live則只統計活物件
jmap -dump:live,format=b,file=heapLive.hprof 6 jmap把程序記憶體使用情況dump到檔案中,或者dump**.hprof**檔案,在本地使用MAT(Eclipse Memory Analyzer)進行分析。也可以直接用jhat分析檢視
jmap -heap 10765
檢視新生代,老生代堆記憶體的分配大小以及使用情況,看是否本身分配過小
jmap -histo:live 10765 | more
查詢最耗記憶體的物件 以表格的形式顯示存活物件的資訊,並按照所佔記憶體大小排序
jmap -dump:format=b,file=dumpfile.hprof pid
使用jmap生成堆轉儲檔案 使用JProfiler、MAT記憶體分析。

jmap -dump:format=b, file=dumpfile.hprof pid
docker cp 29198c060396:/dumpfile.hprof .
匯出jmap dump的檔案,進一步分析,copy docker中的檔案到宿主機

jmap -heap pid
檢視程序堆記憶體使用情況,包括使用的GC演算法、堆配置引數和各代中堆記憶體使用情況

jmap -histo[:live] pid
檢視堆記憶體中的物件數目、大小統計直方圖,如果帶上live則只統計活物件

jmap -dump
把程序記憶體使用情況dump到檔案中,再用jhat分析檢視
jmap -dump:format=b,file=heapdump.hprof pid
dump出來的檔案可以用MAT、VisualVM等工具檢視,用jhat檢視命令:
jhat -port 9998 /tmp/dump.dat
注意如果Dump檔案太大,可能需要加上-J-Xmx512m這種引數指定最大堆記憶體,即jhat -J-Xmx512m -port 9998 /tmp/dump.dat。然後就可以在瀏覽器中輸入主機地址:9998查看了

jstack 檢視執行緒資訊
jstack pid
jstack -l 6 用來檢視Java程序內的執行緒堆疊資訊。

jstat 效能分析 (JVM統計監測工具)
Docker容器中使用jstat過程
列出docker容器:docker ps
標準輸入和關聯終端:docker exec -it 容器ID /bin/bash
查找出java程序: ps – ef | grep java
統計gc資訊統計: jstat –gcutil 466 3000 每三秒列印一次

語法格式如下:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
vmid是虛擬機器ID,在Linux/Unix系統上一般就是程序ID。
interval是取樣時間間隔。
count是取樣數目。比如下面輸出的是GC資訊,取樣時間間隔為250ms,取樣數為4
命令:
jstat -gc 21711 250 4
堆記憶體 = 年輕代 + 年老代 + 永久代
年輕代 = Eden區 + 兩個Survivor區(From和To)

1.jstat -gc pid
可以顯示gc的資訊,檢視gc的次數,及時間。
其中最後五項,分別是young gc的次數,young gc的時間,full gc的次數,full gc的時間,gc的總時間。
2.jstat -gccapacity pid
可以顯示,VM記憶體中三代(young,old,perm)物件的使用和佔用大小,
如:PGCMN顯示的是最小perm的記憶體使用量,PGCMX顯示的是perm的記憶體最大使用量,
PGC是當前新生成的perm記憶體佔用量,PC是但前perm記憶體佔用量。
其他的可以根據這個類推, OC是old內純的佔用量。
3.jstat -gcutil pid
統計gc資訊統計。
4.jstat -gcnew pid
年輕代物件的資訊。
5.jstat -gcnewcapacity pid
年輕代物件的資訊及其佔用量。
6.jstat -gcold pid
old代物件的資訊。
7.stat -gcoldcapacity pid
old代物件的資訊及其佔用量。
8.jstat -gcpermcapacity pid
perm物件的資訊及其佔用量。
9.jstat -class pid
顯示載入class的數量,及所佔空間等資訊。
10.jstat -compiler pid
顯示VM實時編譯的數量等資訊。
11.stat -printcompilation pid
當前VM執行的資訊。
jstat -gccause pid 1 每格1毫秒輸出結果
jstat -gccause pid 3000 每格3秒輸出結果

圖中引數含義如下:
S0 — Heap上的 Survivorspace 0 區已使用空間的百分比
S1 — Heap上的 Survivorspace 1 區已使用空間的百分比
E — Heap上的 Eden space區已使用空間的百分比
O — Heap上的 Old space 區已使用空間的百分比
P — Perm space 區已使用空間的百分比
YGC — 從應用程式啟動到取樣時發生 YoungGC 的次數
YGCT –從應用程式啟動到取樣時 Young GC 所用的時間(單位秒)
FGC — 從應用程式啟動到取樣時發生 Full GC的次數
FGCT –從應用程式啟動到取樣時 Full GC 所用的時間(單位秒)
GCT — 從應用程式啟動到取樣時用於垃圾回收的總時間(單位秒)

S0C、S1C、S0U、S1U:Survivor 0/1區容量(Capacity)和使用量(Used)
EC、EU:Eden區容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年輕代GC次數和GC耗時
FGC、FGCT:Full GC次數和Full GC耗時
GCT:GC總耗時

檢視jvm 配置資訊
docker exec -it xxx /bin/sh

java -XX:+PrintCommandLineFlags 列印jvm啟動引數配置
java -XX:+PrintGCDetails 列印GC執行資訊

jinfo -flags pid docker 容器內java程序pid預設為1

記憶體分析工具
jvisualvm jdk自帶的工具
mac 終端 直接執行 jvisualvm

jconsole jdk 工具
mac 終端直接執行 jconsole

JProfiler
mat
Java 記憶體洩漏排查
mat

gc.log分析
gceasy

參考文件:
難忘的OOM緝凶之旅

Docker java程式jvm分析