调试与定位
思维导图
一、基础故障处理工具
jmap
-
jmap pid
- 查看进程的内存映像信息
- 使用不带选项的参数的jmap打印共享内存映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射到校以及共享对应对象文件的路径全称。
-
jmap -heap pid
- 显示java堆详细信息
- 打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和个内存区域内存使用信息
-
jmap -histo:live pid
- 显示堆中对象的统计信息
- 其中包括每隔java类、对象数量、内存大小(字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个‘*’前缀。如果执行了live子选项,则只计算活动的对象。
-
jmap -clstats pid
- 打印类加载器信息
- -clstats是-permstat的替代。打印java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。字符串数量和大小和会被打印
-
jmap -finalizerinfo pid
- 打印等待终结的对象信息。
-
jamp -dump;format=b,file=heapdump.phrof pid
- 生成堆转储快照dump文件
- 以hprof二进制格式转储java✔到执行filename的文件中。live子选项可选,选中表示堆中只有活动的对象会被转储。浏览dump的话,可以使用jhat(java堆分析工具读取生成的文件)
Jmap (Memory Map for Java) Java内存映像工具
- 作用: 生成堆转储快照(dump文件);查询finalize执行队列、java堆和方法区的详细信息。
- 用法:
jmap [option] <pid>
- 参数说明:
-heap
: 显示java堆的详细信息-histo[:live]
: 显示堆中对象的统计信息(常用)-clstats
: 打印类加载器信息-finalizerinfo
: 打印等待终结的对象信息-dump;<dump-options>
: 生成dump文件(常用),jmap -dump:live,format=b,file=heap.bin-F
: 强制生成dump文件
Jhat (JVM heap Analysis Tool) 虚拟机堆转储快照分析工具
- 作用: 与jmap搭配使用,分析jmap生成的堆转储快照
- 用法:
jhat [-stack <bool>][-refs <bool>][-port <port>][-baseline <file>][-debug <int>][-version][-h|-help] <file>
- 说明: 不常用,通常用VisualVM等工具分析转储快照文件
Jps (JVM Process Status Tool) 虚拟机进程状况工具
- 作用:列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID
- 用法:
jps [-q][-mlvV][<hostid>]
- 参数说明
-q
: 输出进程id-m
: 输出进程ID、主类名称、虚拟机进程启动时传递给主类main方法的参数-l
: 输出进程ID、主类全名(常用)-v
: 输出进程ID、主类名称、虚拟机进程启动时的JVM参数-V
: 输出进程ID、主类名称
Jstack (Stack Trace for Java) Java堆栈跟踪工具
- 作用: 生成虚拟机当前时刻的线程快照,定位线程出现长时间停顿的原因
- 用法:
jstack [option] <pid>
- 参数说明
-F
: 强制输出线程堆栈-m
: 同时输出java、C/C++的堆栈信息-l
: 除堆栈外,显示关于锁的附加信息
Jstat (JVM Statistics Monitoring Tool) 虚拟机统计信息检视工具
- 作用: 监视虚拟机各种运行状态信息,显示本地/远程虚拟机进程中的类加载、内存、垃圾收集等运行时数据
- 用法:
jstat -<option> [-t][-h<lines>]<vmid>[<interval>][<count>]
- 参数说明
- options参数:
-class
: 类加载器统计信息-compiler
:编译统计信息-gc
:垃圾收集统计信息(常用)-gcutil
:垃圾收集统计信息(百分比)
-t
: 显示系统运行时间-h
: 输出lines行后输出表头vmid
: 进程IDinternal
: 执行时间间隔count
: 执行次数
- options参数:
Jinfo (Configuration Info for Java) Java配置信息工具
- 作用: 实时查看和调整虚拟机各项参数
- 用法:
jinfo [option]<pid>
- 参数说明
-flag <name>
: 查看执行的jvm参数的值-flag [+][-]<name>
: 开启或关闭对应名称的参数-flag <name>=<value>
: 修改指定参数的值-flags
: 输出全部的虚拟机参数(常用)-sysprops
: 输出当前虚拟机进程的全部系统属性(常用)
二、可视化故障处理工具
1. JConsole(Java Monitoring and Management Console):Java监视与管理控制台
- 启动: 执行jconsole 概览中包括4张图表:内存、线程、类、CPU占用率。
- 内存监控: 内存分为两大类
- 堆内存: Eden Space、Survivor Spacd、 Tenured Gen
- 非堆内存: Metaspace、Code Cache、Compressed Class Space - 线程监控: 查看线程堆栈;可以监测死锁。
- 类监控: 显示类加载信息
- VM概要: 显示系统信息、VM参数等。
2. VisualVM (All-in-One Java Troubleshooting Tool): 多合一故障处理工具
- 启动: 双击exe启动插件
- Monitor: 包含CPU、堆、类、线程图表;点击heap dump生成堆转储快照文件,可以查看Summary、Objects、Threads信息。
- Threads: 包含线程相关信息、死锁诊断。
- Visual GC: 垃圾回收检视
- Tracer: 监测运行
- Sampler: CPU和Memory采样,进行占用分析
- Profiler: 性能分析,包括CPU、Memory、JDBC。
- JConsole Plugins。
3. JMC (Java Mission Control): 可持续在线的监控工具
- 启动: 双击exe启动插件
4. MAT (Memort Analyzer Tool): 内存分析工具
三、常用Linux诊断命令
- strace: 追踪系统调用。获取进程的动态信息,获取系统级调用,即程序现在在干什么。
用法举例:strace -o strace.txt -T -tt -e trace=all -p <pid>
- pstack: 显示进程的线程堆栈快照,区别于jstack显示的java层堆栈信息。
用法举例:pstack <pid> >> pstack.log
- pmap: 查询进程的内存映射关系,经常用于排查内存泄漏。
用法举例:pmap -x <pid>
- vmstat: 监控整个系统的资源使用情况。
用法举例:vmstat
- top: 显示系统中各个进程的资源占用状况
用法举例:top -H -p <pid>
三、 常用lunix诊断命令
JIT
- 设置热点代码阈值的参数: -XX:CompoleThreshold=500
JPDA 标准调试框架
-
组成
- JVM TI: 整套调试体系的能力
- JDWP: 定义调试者和被调试者之间的通信协议
- JDI: 直接面向调试器开发人员的前端接口
-
JVM TI提供典型能力 (归属在java程序里面)
- 各类事件的钩子(比如类加载)
- java对应操控
- java线程和锁操控
- 基本调试原语(比如断点)
-
JVM TI Agent加载方式 (基于Instrumentation机制)
- 在JVM启动的时候通过命令行选项执行Agent加载 -agentlib 或 -agentpath
- 在JVM运行时加载(attach机制)
参数设置
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
-Xmx3550m:设置JVM最大可用内存为3550M.
-Xms3550m:设置JVM促使内存为3550m.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存.
-Xmn2g:设置年轻代大小为2G.整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8.
-Xss128k:设置每个线程的堆栈大小.JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右.
堆设置
-Xms:初始堆大小
-Xmx:最大堆大小
-XX:NewSize=n:设置年轻代大小
-XX:NewRatio=n:设置年轻代和年老代的比值.如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值.注意Survivor区有两个.如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
-XX:MaxPermSize=n:设置持久代大小
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
垃圾回收统计信息
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数.并行收集线程数.
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比.公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式.适用于单CPU情况.
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数.并行收集线程数.
Heap设定与垃圾回收Java Heap分为3个区,Young,Old和Permanent.Young保存刚实例化的对象.当该区被填满时,GC会将对象移到Old区.Permanent区则负责保存反射对象