如何使用JVM监控及故障处理工具解决复杂运行时问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2546个文字,预计阅读时间需要11分钟。
目录
1.JVM参数
2.Sun JDK监控和故障处理工具
- jps:虚拟机进程状态工具 - jstat:虚拟机系统信息监视工具 - jmap:Java内存映射工具 - jhat:JVM堆快照分析工具 目录1JVM参数2SunJDK监控和故障处理工具jps:虚拟机进程状况工具jstat:虚拟机统计信息监视工具jmap:java内存映射工具jhat:jvm堆快照分析工具目录
1 JVM参数
2 SunJDK监控和故障处理工具
jps: 虚拟机进程状况工具
jstat: 虚拟机统计信息监视工具
jmap: java 内存映射工具
jhat:jvm堆快照分析工具
jstack:java堆栈跟踪工具
jinfojava配置信息
3 JDK的可视化工具
4 应用
1、cpu飙升
2、线程死锁
3、OOM内存泄露
1 JVM参数
参数分类
- 1.标准参数 功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数
- 2.X参数 非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 但是注意没有-Xcomp
- 3.XX参数 非标准 很长一段时间不会列出来 用于JVM开发的debug和调优
2 SunJDK监控和故障处理工具
名称
主要作用jpsjvm process status tool,显示指定系统内所有的hotspot虚拟机进程jstatjvm statistics monitoring tool,用于收集hotspot虚拟机各方面的运行数据jinfoconfiguration info for java显示虚拟机配置信息jmapmemory map for java,生成虚拟机的内存转储快照heapdump文件jhatjvm heap dump browser用于分析heapmap文件它会建立一个堆内存使用情况PS Young GenerationEden Space://Eden区内存分布capacity 33030144 (31.5MB)//Eden区总容量used 1524040 (1.4534378051757812MB) //Eden区已使用free 31506104 (30.04656219482422MB) //Eden区剩余容量4.614088270399305% used //Eden区使用比率From Space: //其中一个Survivor区的内存分布capacity 5242880 (5.0MB)used 0 (0.0MB)free 5242880 (5.0MB)0.0% usedTo Space: //另一个Survivor区的内存分布capacity 5242880 (5.0MB)used 0 (0.0MB)free 5242880 (5.0MB)0.0% usedPS Old Generation //当前的Old区内存分布capacity 86507520 (82.5MB)used 0 (0.0MB)free 86507520 (82.5MB)0.0% usedPS Perm Generation//当前的 “永生代” 内存分布capacity 22020096 (21.0MB)used 2496528 (2.3808746337890625MB)free 19523568 (18.619125366210938MB)11.337498256138392% used 670 interned Strings occupying 43720 bytes.
可以很清楚的看到Java堆中各个区域目前的情况。
-histo
打印堆的对象统计包括对象数、内存大小等等 因为在dump:live前会进行full gc如果带上live则只统计活对象因此不加live的堆大小要大于加live堆的大小
$ jmap -histo:live 28920 | morenum #instances #bytes class name----------------------------------------------1: 83613 12012248 2: 23868 11450280 [B3: 83613 10716064 4: 76287 10412128 [C5: 8227 9021176 6: 8227 5830256 7: 7031 5156480 8: 73627 1767048 java.lang.String9: 2260 1348848 10: 8856 849296 java.lang.Class....
jhat:jvm堆快照分析工具
jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用用来分析jmap生成的dumpjhat内置了一个微型的HTTP/HTML服务器生成dump的分析结果后可以在浏览器中查看。在此要注意一般不会直接在服务器上进行分析因为jhat是一个耗时并且耗费硬件资源的过程一般把服务器生成的dump文件复制到本地或其他机器上进行分析。
命令格式
jhat [dumpfile]
参数
-
-stack false|true 关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true.>
-
-refs false|true 关闭对象引用跟踪(tracking of references to objects)。 默认值为 true. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。>
-
-port port-number 设置 jhat HTTP server 的端口号. 默认值 7000.>
-
-exclude exclude-file 指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。>
-
-baseline exclude-file 指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.>
-
-debug int 设置 debug 级别. 0 表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.>
-
-version 启动后只显示版本信息就退出>
-
-J 因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.
示例
$ jhat -J-Xmx512m dump.hprofeading from dump.hprof...Dump file created Fri Mar 11 17:13:42 CST 2016Snapshot read, resolving...Resolving 271678 objects...Chasing references, expect 54 dots......................................................Eliminating duplicate references......................................................Snapshot resolved.Started HTTP server on port 7000Server is ready.
中间的-J-Xmx512m是在dump快照很大的情况下分配512M内存去启动HTTP服务器运行完之后就可在浏览器打开Http://localhost:7000进行快照分析 堆快照分析主要在最后面的Heap Histogram里里面根据class列出了dump的时候所有存活对象。
jstack:java堆栈跟踪工具
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合生成线程快照的主要目的是定位线程出现长时间停顿的原因如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈就可以知道没有响应的线程到底在后台做什么事情或者等待什么资源。 如果java程序崩溃生成core文件jstack工具可以用来获得core文件的java stack和native stack的信息从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外jstack工具还可以附属到正在运行的java程序中看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态jstack是非常有用的。
命令格式
jstack [option] LVMID
option参数
-
-F : 当正常输出请求不被响应时强制输出线程堆栈
-
-l : 除堆栈外显示关于锁的附加信息
-
-m : 如果调用到本地方法的话可以显示C/C的堆栈
示例
$ jstack -l 11494|more2016-07-28 13:40:04Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):"Attach Listener" daemon prio10 tid0x00007febb0002000 nid0x6b6f waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"http-bio-8005-exec-2" daemon prio10 tid0x00007feb94028000 nid0x7b8c waiting on condition [0x00007fea8f56e000]java.lang.Thread.State: WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None.....
jinfojava配置信息
jinfo(JVM Configuration info)这个命令作用是实时查看和调整虚拟机运行参数。 之前的jps -v口令只能查看到显示指定的参数如果想要查看未被显示指定的参数的值就要使用jinfo口令
命令格式
jinfo [option] [args] LVMID
option参数
-
-flag : 输出指定args参数的值
-
-flags : 不需要args参数输出所有JVM参数的值
-
-sysprops : 输出系统属性等同于System.getProperties()
示例
$ jinfo -flag 11494-XX:CMSInitiatingOccupancyFraction80
3 JDK的可视化工具
对jvm监控的常见可视化工具除了jdk本身提供的Jconsole和visualVm以外还有第三方提供的jprofilterperfino,YourkitPerf4jJProbeMAT等。这些工具都极大的丰富了我们定位以及优化jvm方式。
这些工具的使用网上有很多教程提供这里就不再过多介绍了。对于VisualVm来说比较推荐使用它除了对jvm的侵入性比较低以外还是jdk团队自己开发的相信以后功能会更加丰富和完善。jprofilter对于第三方监控工具提供的功能和可视化最为完善目前多数ide都支持其插件对于上线前的调试以及性能调优可以配合使用。
另外对于线上dump的heap信息应该尽量拉去到线下用于可视化工具来分析这样分析更详细。如果对于一些紧急的问题必须需要通过线上监控可以采用 VisualVm的远程功能来进行这需要使用tool.jar下的MAT功能。
4 应用 1、cpu飙升
在线上有时候某个时刻可能会出现应用某个时刻突然cpu飙升的问题。对此我们应该熟悉一些指令快速排查对应代码。
1.找到最耗CPU的进程
指令:top
2.找到该进程下最耗费cpu的线程
指令:top -Hp pid
3.转换进制
printf “%x\n” 15332 // 转换16进制转换后为0x3be4
4.过滤指定线程打印堆栈信息
指令:jstack pid |grep threadPid -C5 --color jstack 13525 |grep 0x3be4 -C5 --color // 打印进程堆栈 并通过线程id过滤得到线程堆栈信息。
可以看到是一个上报程序占用过多cpu了以上例子只为示例本身耗费cpu并不高
2、线程死锁
有时候部署场景会有线程死锁的问题发生但又不常见。此时我们采用jstack查看下一下。比如说我们现在已经有一个线程死锁的程序导致某些操作waiting中。
1.查找java进程id
指令:top 或者 jps
2.查看java进程的线程快照信息
指令jstack -l pid
从输出信息可以看到有一个线程死锁发生并且指出了那行代码出现的。如此可以快速排查问题。
3、OOM内存泄露
java堆内的OOM异常是实际应用中常见的内存溢出异常。一般我们都是先通过内存映射分析工具比如MAT对dump出来的堆转存快照进行分析确认内存中对象是否出现问题。
当然了出现OOM的原因有很多并非是堆中申请资源不足一种情况。还有可能是申请太多资源没有释放或者是频繁频繁申请系统资源耗尽。针对这三种情况我需要一一排查。
OOM的三种情况:
1.申请资源内存过小不够用。
2.申请资源太多没有释放。
3.申请资源过多资源耗尽。比如线程过多线程内存过大等。
1.排查申请申请资源问题。
指令:jmap -heap 11869
查看新生代老生代堆内存的分配大小以及使用情况看是否本身分配过小。
3.查找最费内存的对象
指令: jmap -histo:live 11869 | more
上述输出信息中最大内存对象才161kb,属于正常范围。如果某个对象占用空间很大比如超过了100Mb应该着重分析为何没有释放。
注意上述指令:
jmap -histo:live 11869 | more执行之后会造成jvm强制执行一次fgc在线上不推荐使用可以采取dump内存快照线下采用可视化工具进行分析更加详尽。jmap -dump:formatb,file/tmp/dump.dat 11869 或者采用线上运维工具自动化处理方便快速定位遗失出错时间。
4.确认资源是否耗尽
- pstree 查看进程线程数量
- netstat 查看网络连接数量
或者采用:
- ll /proc/${PID}/fd | wc -l // 打开的句柄数
- ll /proc/${PID}/task | wc -l 效果等同pstree -p | wc -l //打开的线程数
参考
JVM性能监控与故障处理工具
深入理解JVM虚拟机9JVM监控工具与诊断实践
理解jvm故障处理工具
本文共计2546个文字,预计阅读时间需要11分钟。
目录
1.JVM参数
2.Sun JDK监控和故障处理工具
- jps:虚拟机进程状态工具 - jstat:虚拟机系统信息监视工具 - jmap:Java内存映射工具 - jhat:JVM堆快照分析工具 目录1JVM参数2SunJDK监控和故障处理工具jps:虚拟机进程状况工具jstat:虚拟机统计信息监视工具jmap:java内存映射工具jhat:jvm堆快照分析工具目录
1 JVM参数
2 SunJDK监控和故障处理工具
jps: 虚拟机进程状况工具
jstat: 虚拟机统计信息监视工具
jmap: java 内存映射工具
jhat:jvm堆快照分析工具
jstack:java堆栈跟踪工具
jinfojava配置信息
3 JDK的可视化工具
4 应用
1、cpu飙升
2、线程死锁
3、OOM内存泄露
1 JVM参数
参数分类
- 1.标准参数 功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数
- 2.X参数 非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 但是注意没有-Xcomp
- 3.XX参数 非标准 很长一段时间不会列出来 用于JVM开发的debug和调优
2 SunJDK监控和故障处理工具
名称
主要作用jpsjvm process status tool,显示指定系统内所有的hotspot虚拟机进程jstatjvm statistics monitoring tool,用于收集hotspot虚拟机各方面的运行数据jinfoconfiguration info for java显示虚拟机配置信息jmapmemory map for java,生成虚拟机的内存转储快照heapdump文件jhatjvm heap dump browser用于分析heapmap文件它会建立一个堆内存使用情况PS Young GenerationEden Space://Eden区内存分布capacity 33030144 (31.5MB)//Eden区总容量used 1524040 (1.4534378051757812MB) //Eden区已使用free 31506104 (30.04656219482422MB) //Eden区剩余容量4.614088270399305% used //Eden区使用比率From Space: //其中一个Survivor区的内存分布capacity 5242880 (5.0MB)used 0 (0.0MB)free 5242880 (5.0MB)0.0% usedTo Space: //另一个Survivor区的内存分布capacity 5242880 (5.0MB)used 0 (0.0MB)free 5242880 (5.0MB)0.0% usedPS Old Generation //当前的Old区内存分布capacity 86507520 (82.5MB)used 0 (0.0MB)free 86507520 (82.5MB)0.0% usedPS Perm Generation//当前的 “永生代” 内存分布capacity 22020096 (21.0MB)used 2496528 (2.3808746337890625MB)free 19523568 (18.619125366210938MB)11.337498256138392% used 670 interned Strings occupying 43720 bytes.
可以很清楚的看到Java堆中各个区域目前的情况。
-histo
打印堆的对象统计包括对象数、内存大小等等 因为在dump:live前会进行full gc如果带上live则只统计活对象因此不加live的堆大小要大于加live堆的大小
$ jmap -histo:live 28920 | morenum #instances #bytes class name----------------------------------------------1: 83613 12012248 2: 23868 11450280 [B3: 83613 10716064 4: 76287 10412128 [C5: 8227 9021176 6: 8227 5830256 7: 7031 5156480 8: 73627 1767048 java.lang.String9: 2260 1348848 10: 8856 849296 java.lang.Class....
jhat:jvm堆快照分析工具
jhat(JVM Heap Analysis Tool)命令是与jmap搭配使用用来分析jmap生成的dumpjhat内置了一个微型的HTTP/HTML服务器生成dump的分析结果后可以在浏览器中查看。在此要注意一般不会直接在服务器上进行分析因为jhat是一个耗时并且耗费硬件资源的过程一般把服务器生成的dump文件复制到本地或其他机器上进行分析。
命令格式
jhat [dumpfile]
参数
-
-stack false|true 关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true.>
-
-refs false|true 关闭对象引用跟踪(tracking of references to objects)。 默认值为 true. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。>
-
-port port-number 设置 jhat HTTP server 的端口号. 默认值 7000.>
-
-exclude exclude-file 指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。>
-
-baseline exclude-file 指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.>
-
-debug int 设置 debug 级别. 0 表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.>
-
-version 启动后只显示版本信息就退出>
-
-J 因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.
示例
$ jhat -J-Xmx512m dump.hprofeading from dump.hprof...Dump file created Fri Mar 11 17:13:42 CST 2016Snapshot read, resolving...Resolving 271678 objects...Chasing references, expect 54 dots......................................................Eliminating duplicate references......................................................Snapshot resolved.Started HTTP server on port 7000Server is ready.
中间的-J-Xmx512m是在dump快照很大的情况下分配512M内存去启动HTTP服务器运行完之后就可在浏览器打开Http://localhost:7000进行快照分析 堆快照分析主要在最后面的Heap Histogram里里面根据class列出了dump的时候所有存活对象。
jstack:java堆栈跟踪工具
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合生成线程快照的主要目的是定位线程出现长时间停顿的原因如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈就可以知道没有响应的线程到底在后台做什么事情或者等待什么资源。 如果java程序崩溃生成core文件jstack工具可以用来获得core文件的java stack和native stack的信息从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外jstack工具还可以附属到正在运行的java程序中看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态jstack是非常有用的。
命令格式
jstack [option] LVMID
option参数
-
-F : 当正常输出请求不被响应时强制输出线程堆栈
-
-l : 除堆栈外显示关于锁的附加信息
-
-m : 如果调用到本地方法的话可以显示C/C的堆栈
示例
$ jstack -l 11494|more2016-07-28 13:40:04Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):"Attach Listener" daemon prio10 tid0x00007febb0002000 nid0x6b6f waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLELocked ownable synchronizers:- None"http-bio-8005-exec-2" daemon prio10 tid0x00007feb94028000 nid0x7b8c waiting on condition [0x00007fea8f56e000]java.lang.Thread.State: WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104)at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:745)Locked ownable synchronizers:- None.....
jinfojava配置信息
jinfo(JVM Configuration info)这个命令作用是实时查看和调整虚拟机运行参数。 之前的jps -v口令只能查看到显示指定的参数如果想要查看未被显示指定的参数的值就要使用jinfo口令
命令格式
jinfo [option] [args] LVMID
option参数
-
-flag : 输出指定args参数的值
-
-flags : 不需要args参数输出所有JVM参数的值
-
-sysprops : 输出系统属性等同于System.getProperties()
示例
$ jinfo -flag 11494-XX:CMSInitiatingOccupancyFraction80
3 JDK的可视化工具
对jvm监控的常见可视化工具除了jdk本身提供的Jconsole和visualVm以外还有第三方提供的jprofilterperfino,YourkitPerf4jJProbeMAT等。这些工具都极大的丰富了我们定位以及优化jvm方式。
这些工具的使用网上有很多教程提供这里就不再过多介绍了。对于VisualVm来说比较推荐使用它除了对jvm的侵入性比较低以外还是jdk团队自己开发的相信以后功能会更加丰富和完善。jprofilter对于第三方监控工具提供的功能和可视化最为完善目前多数ide都支持其插件对于上线前的调试以及性能调优可以配合使用。
另外对于线上dump的heap信息应该尽量拉去到线下用于可视化工具来分析这样分析更详细。如果对于一些紧急的问题必须需要通过线上监控可以采用 VisualVm的远程功能来进行这需要使用tool.jar下的MAT功能。
4 应用 1、cpu飙升
在线上有时候某个时刻可能会出现应用某个时刻突然cpu飙升的问题。对此我们应该熟悉一些指令快速排查对应代码。
1.找到最耗CPU的进程
指令:top
2.找到该进程下最耗费cpu的线程
指令:top -Hp pid
3.转换进制
printf “%x\n” 15332 // 转换16进制转换后为0x3be4
4.过滤指定线程打印堆栈信息
指令:jstack pid |grep threadPid -C5 --color jstack 13525 |grep 0x3be4 -C5 --color // 打印进程堆栈 并通过线程id过滤得到线程堆栈信息。
可以看到是一个上报程序占用过多cpu了以上例子只为示例本身耗费cpu并不高
2、线程死锁
有时候部署场景会有线程死锁的问题发生但又不常见。此时我们采用jstack查看下一下。比如说我们现在已经有一个线程死锁的程序导致某些操作waiting中。
1.查找java进程id
指令:top 或者 jps
2.查看java进程的线程快照信息
指令jstack -l pid
从输出信息可以看到有一个线程死锁发生并且指出了那行代码出现的。如此可以快速排查问题。
3、OOM内存泄露
java堆内的OOM异常是实际应用中常见的内存溢出异常。一般我们都是先通过内存映射分析工具比如MAT对dump出来的堆转存快照进行分析确认内存中对象是否出现问题。
当然了出现OOM的原因有很多并非是堆中申请资源不足一种情况。还有可能是申请太多资源没有释放或者是频繁频繁申请系统资源耗尽。针对这三种情况我需要一一排查。
OOM的三种情况:
1.申请资源内存过小不够用。
2.申请资源太多没有释放。
3.申请资源过多资源耗尽。比如线程过多线程内存过大等。
1.排查申请申请资源问题。
指令:jmap -heap 11869
查看新生代老生代堆内存的分配大小以及使用情况看是否本身分配过小。
3.查找最费内存的对象
指令: jmap -histo:live 11869 | more
上述输出信息中最大内存对象才161kb,属于正常范围。如果某个对象占用空间很大比如超过了100Mb应该着重分析为何没有释放。
注意上述指令:
jmap -histo:live 11869 | more执行之后会造成jvm强制执行一次fgc在线上不推荐使用可以采取dump内存快照线下采用可视化工具进行分析更加详尽。jmap -dump:formatb,file/tmp/dump.dat 11869 或者采用线上运维工具自动化处理方便快速定位遗失出错时间。
4.确认资源是否耗尽
- pstree 查看进程线程数量
- netstat 查看网络连接数量
或者采用:
- ll /proc/${PID}/fd | wc -l // 打开的句柄数
- ll /proc/${PID}/task | wc -l 效果等同pstree -p | wc -l //打开的线程数
参考
JVM性能监控与故障处理工具
深入理解JVM虚拟机9JVM监控工具与诊断实践
理解jvm故障处理工具

