OOM与调优
6.JVM工具如jps
该命令是纯Java编写的
-q:只显示Java进程的ID
-m:输出Java进程的ID + main函数所在类的名字 + 传递给main函数的参数
-l:输出Java进程的ID+main函数所在类的全限定名(包名+类名)
-v:输出Java进程的ID+main函数所在类的名称+传递给JVM的参数
应用:可以通过次方式快速查看JVM参数是否设置成功
jps源码的位置
/openjdk/jdk/src/share/classes/sun/tools/jps
如何识别的Java进程?jps输出的信息全是Java进程的信息,是如何做到的?
Java进程在创建的时候,会生成相应的文件,进程相关的信息会写入该文件中。Windows下默认路径是:
C:\Users\username\AppData\Local\Temp\hsperfdata_username
Ubuntu环境下,它的路径是
/tmp/hsperfdata_username
PerfData文件
- 1.文件创建
每启动一个Java进程,/tmp/hsperfdata_username就会生成进程号的一个文件,这个文件是一个内存映射文件。有时候不会生成,受参数的影响,
-XX:-/+UsePerfData默认是开启的,它是通过attach到Java进程中去,它属于寄生在Java进程当中,可以读取Java进程的内存。
-XX:-/+PerfDisableSharedMem(禁用共享内存)默认是关闭的,即支持内存共享。如果禁用了,依赖于PerfData文件的工具就无法正常进行了 - 2.文件删除
正常情况下:默认情况下随Java进程的结束而销毁
非正常退出:下一次去读目录的时候会检测进程是否存在, 用kill -0 去检测进程是否存活,不存货就会删除该进程号文件,不然就会留下垃圾文件 - 3.文件更新
-XX:PerfDataSamplingInterval=50,即内存与PerfData文件的数据延迟为50ms
查看PerfData参数
7.JVM异常退出
- OOM killer
dmesg -T 日志查看内核日志 - 堆OOM
会生成日志,分配内存new的执行流程 - 元空间OOM
会生成日志,解析类、类加载器、动态字节码 cglib - 直接内存OOM
unsafe bytbuffer
都不会生成日志,JVM进程的堆(OS知道) - 栈OOM,为什么没有听说过这个地方发生OOM
开发阶段就会知道栈帧是否会发生OOM了
CPU占用过高如何排查?
- 1.定位到占用CPU最高的进程
- 2.定位到目前占用CPU最高的线程ID
top -H -p pid
将线程ID由十进制转换为十六进制
- 3.定位线程
jstack pid | grep 十六进制线程id -A 30