JVM-18-JVM监控及诊断工具之命令行

JVM-18-JVM监控及诊断工具之命令行

以下使用<>括起来的是参数, [] 括起来的是可选填

jps

  • 查看正在运行的Java进程, 显示指定系统内所有的HotSpot虚拟机进程, 对本地虚拟机进程来说, 进程的本地虚拟机ID与操作系统的进程ID是一致的
  • 语法: jps [-q] [-mlvV] [<hostid>]
  • options参数:
    • -q: 只显示进程ID,不显示主类名称
    • -l : 输出应用程序主类的全类名, 如果进程执行的是jar包, 则输出jar完整路径
    • -m: 输出虚拟机进程启动时传递给主类main的参数
    • -v: 输出虚拟机进程启动时的jvm参数,如 -Xms20m
  • hostid参数:
    • 如果想要使用该参数访问远程java程序, 需要安装jstatd, 但是容易受到IP地址欺诈攻击
    • 格式:<hostname>[:<port>]:

如果java进行关闭了UsePerfData参数, 即使用了 -XX:-UsePerfData,那么使用jps命令将无法探知到该进程

jstat

  • 用于监视虚拟机各种运行状态信息, 可以显示本地或远程虚拟机进程中的类装载, 内存, 垃圾收集, JIT编译等运行数据, 常用语检查垃圾回收问题和内存泄漏问题

  • 语法: jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

  • option参数:

    • -class: 显示ClassLoader的相关信息: 类的装载\卸载数量, 总空间, 类装载所消耗的时间等
    • -gc: 显示与GC相关的堆信息, 包括Eden区, Survivor区, 老年代, 永久代等的容量, 已用空间, Gc时间合计等信息
      • 新生代相关
        • S0C, 第一个幸存者区的大小
        • S1C, 第二个幸存者区的大小
        • S0U, 第一个幸存者区已使用的大小
        • S1U, 第二个幸存者区已使用的大小
        • EC, Eden区大小
        • EU, Eden区已使用大小
      • 老年代相关
        • OC, 老年区的大小
        • OU, 老年区已使用大小
      • 元空间(方法区)相关
        • MC, 方法区大小
        • MU, 方法区已使用大小
        • CCSC, 压缩类空间的大小
        • CCSU, 压缩类空间已使用大小
      • 其他
        • YGC, 程序从启动到采样时, young GC的次数
        • YGCT, 程序从启动到采样时, young GC消耗的时间(秒)
        • FGC, 程序从启动到采样时, full GC的次数
        • FGCT, 程序从启动到采样时, full GC消耗的时间(秒)
        • GCT, 程序从启动到采样,GC消耗的总时间
    • -gccapacity: 显示内容与-gc基本相同, 主要关注Java堆各个区域使用到的最大最小空间
    • -gccause: 与-gcutil功能一样, 但是会额外输出导致最后一次会当前正在发生gc的原因
    • -gcmetacapacity: 显示元空间使用到的最大最小空间(java8之后使用)

    java7之前使用 -gcpermcapacity显示永久代使用到的最大最小空间

    • -gcnew: 显示新生代GC状况
    • -gcnewcapacity: 显示内容与-gcnew基本相同, 输出主要关注使用到的最大最小空间
    • -gcold: 显示老年代GC状况
    • -gcoldcapacity: 显示内容与-gcold基本相同, 输出主要关注使用到的最大最小空间
    • -gcutil: 显示内容与-gc基本相同, 但主要关注已使用空间占总空间的百分比
    • -compiler: 显示JIT编译器编译过的方法, 耗时信息等
    • -printcompilation: 输出已经被JIT编译的方法
  • -t参数: 在输出内容中添加一个时间, 显示程序运行的时间, 单位秒

    • 可以通过该参数, 获得GC时间占运行时间的比例
    • 如果该比例超过20%, 说明目前堆的压力较大, 超过90%, 说明堆里几乎没有可用空间, 随时可能抛出OOM
  • -h参数: 在周期性数据输出时, 输出多少行数据后输出一个表头信息

  • <vmid>: 进程id

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

  • count参数: 用于指定查询的总次数

判断内存泄漏

  • 在长时间的运行Java程序中, 获取OU列的最小值
  • 每隔一段时间重复上次操作, 获取多组OU最小值, 如果这些值成上升趋势, 说明老年代内存使用量在不断上涨, 也就是说无法回收的对象在不断增加, 因此很有可能存在内存泄漏

jinfo

  • 实时查看和修改JVM的配置参数

  • 语法:

    • 查看:
      • jinfo -sysprops PID : 查看由System.getProperties()取得的参数
      • jinfo -flags PID : 查看曾经附赋过值的一些参数
      • jinfo -flag 参数名 PID : 查看某个进行的具体参数
    • 修改:
      • boolean类型: jinfo -flag [+|-]参数名 PID
      • 非Boolean类型: jinfo -flag 参数名=参数值

    jinfo修改参数后, 部分参数会立即生效, 这部分参数带有manageable 的flag可以被实时修改

    JVM-18-JVM监控及诊断工具之命令行

PrintFlags:

  • java -XX:+PrintFlagsInitial 查看所有 JVM参数的初始值
  • java -XX:+PrintFlagsFinal 查看所有参数的最终值
  • java -XX:+PrintCommandLineFlags 查看用户或jvm设置过的详细的参数名称和值

jmap

  • 导出内存映像文件和内存使用情况, 即获取dump文件(二进制文件)和Java堆各区域的使用情况,类加载信息等

  • 语法:jmap [option] <pid>

  • option参数:

    • -dump: 生成Java堆转储快照dump文件, -dump:live 只保存堆中的存活对象
    • -heap: 输出整个堆空间的详细信息, 包括GC的使用、堆配置信息,已经内存的
    • -histo[:live]:输出堆中对象的统计信息,包括类、实例数量和合计容量,-histo:live 只统计堆中的存货对象
    • -finalizerinfo: 显示在F-Queue中等待Finalizer线程执行finalize方法的对象

    JVM-18-JVM监控及诊断工具之命令行

    • -clstats:以ClassLoader为统计口径输出永久代的内存状态信息, JDK7使用的是-permstat, JDK8以后使用的都是clstats

    JVM-18-JVM监控及诊断工具之命令行

    • -F: 当虚拟机进程 对dump选项没有任何响应是. 可以使用此选项强制执行生成dump文件

    -finalizerinfo, -clstats,-F,老师课件上说该命令只在linux/solaris平台有效,但是经测试在windows上也起作用了,推断应该是JDK7不能在Windows上生效

    • -J: 传递参数给jmap启动的JVM
  • 使用:

    • 导出内存映像文件:

      • 手动:

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

        format=b: 为了生成的文件可以和hprof匹配

      • 自动:

        • -XX:+HeapDumpOnOutOfMemoryError
        • -XX:HeapDumpPath=<filename.hprof>

      Dump文件又叫做堆存储文件, 指一个Java进程在某个时间点的内存快照, 通常在生成Dump文件之前会触发一次FullGC, 所有dump文件保存的都是FullGC后留下的信息, 包括: 所有的对象,类,GC Roots, JVM可达的对象, 线程栈和本地变量

    • 显示堆内存相关信息:

      • jmap -heap pid
      • jmap -histo
    • 其他:

      • jmap -finalizerinfo pid 查看堆积在finalizer队列中的对象
      • jmap -clstats pid 查看系统ClassLoader信息
  • jmap在访问堆中的所有对象,为了保证此过程不被应用程序干扰,jmap借助了安全点机制, 让所有线程停留在不改变堆中数据的状态, 也就是说, 使用jmap导出的堆快照必定是安全点位置的, 并不是实时的,这可能导致基于该快照的分析结果存在误差. 另外如果某个线程长时间无法跑到安全点, jmap将一直等待下去, 而上面的jstat则不同, 垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置, 而jstat只要取即可

jhat

  • JDK自带的堆分析工具,与jmap配合使用, 用于 分析金毛生成的dump文件, jhat内置了一个微型的 HTTP/HTML服务器, 生成dump文件的分析结果后, 用户可以在浏览器中查看分析结果

  • 使用jhat命令就启动了一个http服务, 端口是7000.

    JVM-18-JVM监控及诊断工具之命令行

  • jhat在JDK9/10中已经被删除, 官方建议使用VisualVM代替

  • 语法: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

  • 参数说明:

    <bool>:true/false

    • -stack: 关闭或开启对象分配调用栈跟踪
    • -refs: 关闭或开启对象引用跟踪
    • -port: 设置jhat HttpServer的端口号
    • -exclude: 执行对象查询时需要排除的数据成员, 后面跟文件名称
    • -baseline: 指定一个基准堆转储
    • -debug: 设置debug级别
      • 0, 无debug输出
      • 1,debug hprof文件
      • 2, debug hprof文件, 无服务
    • -version: 启动后显示版本信息就退出
    • -J<flag>: 传入启动参数,如-J-Xms:512m

jstack

  • 打印JVM中线程快照
  • 用于生产虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪), 线程快照就是指当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合
  • 生产线程快照的作用, 用于定位线程出现长时间停顿的原因, 如线程间死锁, 死循环, 请求外部资源导致的长时间等待 等问题,
  • 在thread dump中要注意一下几种状态
    • 死锁,Deadlock
    • 等待资源, Waiting on condition
    • 等待获取监视器, Waiting on monitor entry
    • 阻塞, Block
    • 执行中, Runnable
    • 暂停, Suspended
    • 对象等待中, Object.wait() 或 TIMED_WAITNG
    • 停止,Parked
  • 语法jstack [option] <pid>
  • 参数说明:
    • -F: 强制生成thread dump文件, 当执行jstack长时间没有回应时
    • -m: 如果调用到本地方法的话,可以显示C/C++堆栈
    • -l: 显示关于锁的附加信息

jcmd

  • 多功能命令行工具

  • JDK7之后新增的命令行工具

  • 可以用来实现除了jstat之外所有命令的功能, jcmd拥有jmap的大部分功能, 官方推荐使用jcmd代替jmap

  • 语法:jcmd <pid | main class> <command ...|PerfCounter.print|-f file>

  • 参数说明:

    • -f: 指定命令所在文件
    • -l: 列出本地JVM进程
    • command 具体指令,显示指定指令命令执行后的信息

    command可以是: 一下指令不一定适用于所有进程, 可以使用jcmd pid help查看pid对应进程可以执行的命令

    Compiler.CodeHeap_Analytics
    Compiler.codecache
    Compiler.codelist
    Compiler.directives_add
    Compiler.directives_clear
    Compiler.directives_print
    Compiler.directives_remove
    Compiler.queue
    GC.class_histogram
    GC.class_stats
    GC.finalizer_info
    GC.heap_dump
    GC.heap_info
    GC.run
    GC.run_finalization
    JFR.check
    JFR.configure
    JFR.dump
    JFR.start
    JFR.stop
    JVMTI.agent_load
    JVMTI.data_dump
    ManagementAgent.start
    ManagementAgent.start_local
    ManagementAgent.status
    ManagementAgent.stop
    Thread.print
    VM.class_hierarchy
    VM.classloader_stats
    VM.classloaders
    VM.command_line
    VM.dynlibs
    VM.flags
    VM.info
    VM.log
    VM.metaspace
    VM.native_memory
    VM.print_touched_methods
    VM.set_flag
    VM.start_java_debugging
    VM.stringtable
    VM.symboltable
    VM.system_properties
    VM.systemdictionary
    VM.uptime
    VM.version
    help

jstatd

  • 远程主机信息收集,一般情况不会使用

JVM-18-JVM监控及诊断工具之命令行

上一篇:java内存溢出(OutOfMemoryError)问题排查


下一篇:jmap命令 检查内存泄漏