目录
前言
关于面试和jvm很多时候会问到工具,昨天看了visualVM,今天再把自带的命令行工具好好看看。
如果觉得有帮助给俺点点赞和关注吧~俺以后也想成为布道师!
使用
1.先用jps 查看pid
jps的输出信息包括 Java 进程的进程 ID 以及主类名
-l将打印模块名以及包名;-v将打印传递给 Java 虚拟机的参数(如-XX:+UnlockExperimentalVMOptions -XX:+UseZGC);-m将打印传递给主类的参数。
一般可以这样用:
jps -mlv
Jps -l 更加详细一点
localhost:~ bjhl$ jps -l
419
3171 sun.tools.jps.Jps
3070 org.jetbrains.jps.cmdline.Launcher
不过我还是喜欢jps 简单明了= =,跟jps -l差不多吧
2.jmap
只能查询某一个时刻,堆内存占用的情况。
如果要做一个连续的检测,需要使用jconsole
3.jconsole
多功能检测工具,可以实现连续检测。
所以连续检测,可能得考虑别的工具了
关于jmap:
jmap -h 查看帮助:
jmap -histo 2549
这样是可以用的
但是jmap -heap xxxx
出现下面报错:
ERROR: attach: task_for_pid(2634) failed: '(os/kern) failure' (5)
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process. Could be caused by an incorrect pid or lack of privileges.
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process. Could be caused by an incorrect pid or lack of privileges.
看网上查询是
(mac的锅)
Mac 使用 jinfo 出现:Can't attach to the process. Could be caused by an incorrect pid or lack of privileg
mac的jdk比较特殊,centos没这个问题
有没有解决办法:
查看网上是mac的锅,可以尝试升级JDK来解决,好麻烦。
之前用服务器上的使用就没有这个问题。
在复习一下参数吧。
这是bug
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8161164
jmap都能看什么
查看堆内存的详情信息,主要是在发生OOM,或者发现有此趋势,内存在不断的上升,可以通过此命令来查看分析堆文件,找出内存泄漏的地方。
jmap -heap 8123 //堆的信息
jmap -dump:live,format=b,file=heap.bin 1234 //生成堆的转储文件
其实很少手动dump,可以通过 - XX:+HeapDumpOnOutOfMemeoryError 打印出堆快照文件,只有在发生OOM的时候才生成dump文件,这时候分析dump文件,得到是什么占用了jvm的堆内存导致了OOM,最终的目的是排查问题。
本部分参考链接:https://blog.csdn.net/gogokongyin/article/details/51900828
如何分析jmap的dump文件
使用visualVM,可以看到对象某一时刻内存OOM的 对象详细占用,内存信息等等。
jmap的常用命令
查看整个JVM内存状态
jmap -heap [pid]
会有heap config 和heap的use
对象详细占用
jmap -histo [pid]
导出整个JVM 中内存信息,可以利用其它工具打开dump文件分析,
例如jdk自带的visualvm工具:见:[JVM]visualVM分析java项目的堆栈信息
jmap -dump:file=文件名.dump [pid]
参数
option: 选项参数。
pid: 需要打印配置信息的进程ID。
executable: 产生核心dump的Java可执行文件。
core: 需要打印配置信息的核心文件。
server-id 可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
remote server IP or hostname 远程调试服务器的IP地址或主机名。OPTION
no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。
heap: 显示Java堆详细信息
histo[:live]: 显示堆中对象的统计信息
clstats:打印类加载器信息
finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
dump::生成堆转储快照
F: 当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
help:打印帮助信息
J:指定传递给运行jmap的JVM的参数
如果出现线上问题的分析思路
建议在保留有问题机器的相关堆栈以及线程信息等现场,然后尽快通过重启来让服务进行恢复,接下来可以逐步分析异常原因。
如果web服务出现问题,检查CPU 占用,网络占用以及内存占用。
(PS:看到网上关于网卡:异步调用而且连接未关闭导致千兆网卡的机器被打满的问题,导致服务存在大量超时)这种连接池都应该finally去关闭一下,很久以前我遇到过OSS的链接没关闭的内存泄漏。
1. 用jstat查看jvm的FGC情况。使用
jstat -gcutil 命令查看gc的情况
2. 如果真存在大量的FGC,可以使用jmap来去看:导致FGC的对象
使用jmap存在哪些大对象,导致一直在触发FGC,并进行针对性的优化。
使用的jmap命令如下:jmap -histo:live | head -n 获取目前应用中存活的实例有哪些。
3. 然后查看nginx对应的哪些接口有问题
把nginx服务器上显示504的请求找出来,504响应时间点首次出现,那么大概率就是这个接口导致的 (比如生成大量的对象)导致触发FGC。
确认问题产生的原因之后,做业务上和jvm参数上的调整和限制
参考:
https://blog.csdn.net/weixin_29817227/article/details/112021637