0100-JVM监控及诊断工具-命令行篇

本文详细介绍了如何通过jps检查Java进程、jstat监控JVM性能、jinfo调整配置参数和jmap分析内存状态,帮助开发者理解和优化Java应用。重点讲解了内存监控、垃圾回收分析以及线程快照的捕捉技巧。

1. 监控的意义

使用数据说明问题,使用知识分析问题,使用工具处理问题,无监控,不调优。

2. jps查看正在运行的java进程

1. 基本情况

jps(Java process Status)
显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。

说明:对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

2. 基本用法

-q(quiet): 仅仅显示LVMID(local virtual machine id), 即本地虚拟机唯一id,不显示主类名称等

-l(long): 输出应用程序主类的全类名或进程执行的是jar包,则输出jar完整路径

-m(main): 输出虚拟机进程启动时传递给主类main()的参数

-v(vm options):列出虚拟机进程启动时的JVM参数。比如:-Xms20m -Xmx50m是启动程序指定的jvm参数。

说明:以上参数可以综合使用

补充:
如果某java进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令(jstat)将无法探知java进程


3. jstat查看jvm统计信息

1. 基本情况

jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾收集、JIT编译等运行数据

在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

2. 基本语法

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

2.1 options

  • 类装载相关的

    • -class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类加载所消耗的时间等
  • 垃圾回收相关的

    • -gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等容量、已用空间、GC时间合计等信息。

    • -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。

    • -gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。

    • -gccause:与gcutil功能一样,但是会额外输出导致最后一次或当前正在发生GC产生的原因。

    • -gcnew:显示新生代GC状况

    • -gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间

    • -geold:显示老年代GC状况

    • -gcoldcapacity: 显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间

    • -gcpermcapacity: 显示永久代使用到的最大、最小空间

参数说明

 S0C survivor0区大小(字节)
 S1C survivor1区大小(字节)
 S0U urvivor0区已使用大小(字节)
 S1U urvivor1区已使用大小(字节)
 EC  Eden空间大小(字节) 
 EU  Eden空间已使用大小(字节)     
 OC  老年代大小(字节)      
 OU  老年代已使用大小(字节)    
 MC  方法区(元空间)大小   
 MU  方法区已使用大小 
 CCSC   压缩类空间大小
 CCSU   压缩类空间已使用大小
 YGC    应用程序启动到采样时young gc次数 
 YGCT   应用程序启动到采样时young gc消耗的时间(秒) 
 FGC    应用程序启动到采样时full gc次数 
 FGCT   应用程序启动到采样时full gc消耗的时间(秒)   
 GCT    应用程序启动到采样时gc的总时间
  • JIT相关的
    • -compiler: 显示JIT编译器编译过的方法、耗时等信息
    • -printcompilation:输出已经被JIT编译的方法

2.2 interval

用于指定输出统计数据的周期,单位为毫秒。即:查询间隔

注:每隔多少秒打印一次

2.3 count

用于指定查询的总次数

2.4 -t

可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位秒

经验

我们可以比较java进程的运行时间以及总gc(GCT列),或者两次测量时间的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例

如果该比例超过20%,则说明目前堆压力比较大,如果超过90%,则说明程序大部分时间都在gc,堆里基本没有可用空间,随时都可能抛出oom异常

2.5 -h

可以在周期性数据输出时,输出多少行数据后,输出表头

注:每个多少行,输出一次表头

3. 补充

jstat还可以用来判断是否出现内存泄漏

第一步

在长时间运行的java程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中ou列(即已占用的老年代内存)的最小值

第二步

然后,每隔一段较长时间重复一次上述操作,来获得多组ou最小值。如果这些值呈上涨趋势,则说明该java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。


4. jinfo实时查看和修改JVM配置参数

1. 基本情况

jinfo(Configuration Info for java)
查看虚拟机配置参数信息,也可用于快速调整虚拟机的配置参数

在很多情况下,java应用程序不会指定所有的java虚拟机参数。而此时,开发人员可能不知道某一个具体的java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了jino工具,开发人员可以很方便地找到java虚拟机参数的当前值。

2. 基本语法

  • 查看

    • -sysprops 可以查看由System.getProperties()取得的参数
    • -flags 查看曾经赋过值的一些参数
    • -flag 查看某个java进程具体参数的值
  • 修改(立即生效,manageable参数才可被修改

    • -flag [+|-] 针对boolean类型
    • -flag = 针对非boolean类型

查看可修改参数

java -XX:+PrintFlagsFinal -version | grep manageable

3. 拓展

  • java -XX:+PrintFlagsInitial 查看所有JVM参数启动的初始值
  • java -XX:+PrintFlagsFinal 查看所有JVM参数的最终值
有:的表示用户修改过
bool UseParallelGC                            := true                                {product}
  • java -XX:+PrintCommandLineFlags 查看那些已经被用户或者JVM设置过的详细XX参数的名称和值

5. jmap导出内存映像文件&内存使用情况

1. 基本情况

jmap(JVM Memory Map) 作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标java进程的内存相关信息,包括Java堆各区域的使用情况、堆钟对象的统计信息、类加载信息等

开发人员可以在控制台中输入命令“jmap -help” 查阅jmap工具的具体使用方式和一些标准选项配置。

2. 基本语法

  • -dump
    • 生成java堆转储快照:dump文件
    • 特别的-dump:live只保存堆中的存活对象
  • -heap 给出整个堆空间的详细信息,包括GC的使用、堆配置信息、以及内存的使用信息等
  • histo
    • 输出堆中对象的统计信息、包括类、实例数量和合计容量
    • 特别的-histo:live只统计堆中存活的对象
  • -permstat
    • 以ClassLoader为统计口径输出永久代的内存状态信息
    • 仅linux/solaris平台有效
  • -finalizerinfo
    • 显示在F-Quene中等待Finalizer线程执行finalize方法的对象
    • 仅linux/solaris平台有效
  • F
    • 当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件
    • 仅linux/solias平台有效
  • J 传递参数给jmap启动的jvm

3. 使用

3.1 使用1-导出内存映像文件

手动方式

  • jmap -dump,format=b,file=<filename.hprof>
  • jmap -dump:live,format=b,file=<filename.hprof>

说明

  • format=b 必须加上,后续可以使用jprofiler,jvisualvm等软件打开查看
  • file=<filepath/filename.hprof> 生成的dump文件是hprof格式

使用

jmap -dump:live,format=b,file=f:\1.hprof 4264

自动方式


当程序发生OOM退出系统时,一些瞬间信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。

  • -XX:+HeapDumpOnOutOfMemoryError 当程序发生OOM时,导出运用程序的当前堆快照
  • -XX:HeapDumpPath: 可以指定堆快照的保存位置

使用

-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\m.hprof

3.2 使用2-显示堆内存的相关信息

瞬时堆使用情况,比不上jstat可以实时获取

  • jmap -heap pid
  • jmap -histo pid

3.3 其它做用

  • jmap -permstat pid 查看系统的ClassLoader信息
  • jmap -finalizerinfo 查看堆积在finalizer队列中的对象

4. 总结

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有的线程停留在不改变堆中数据的状态。也就是说,有jmap导出的堆快照必定时安全点位置的。这可能导致基于该快照的分析结果存在偏差(生命周期只存在于两个安全点之间的对象,将不被:live选项探知)

另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去

与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可


6. jstack打印JVM中线程快照

1. 基本介绍

jstack(JVM Stack Trace)用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。

生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。

在thread dump中,要留意下面几种状态

  • 死锁,DeadLock(重点关注)
  • 等待资源,Wait on Condition(重点关注)
  • 等待获取监视器,Waiting on monitor entry(重点关注)
  • 阻塞,Blocked(重点关注)
  • 执行中,Runnable
  • 暂停,Suspended

2. 基本语法

jstack

  • -F 当正常输出的请求不被响应时,强制输出线程堆栈
  • -l 除堆栈外,显示关于锁的附加信息
  • -m 如果调用到本地方法的话,可以显示c/c++的堆栈
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值