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分析
标签:java,OOM,pid,gc,内存,jvm,jstat,docker,jmap 来源: https://www.cnblogs.com/chenqingbin/p/16335005.html