- JVM监控和诊断概述
程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统日志、堆dump文件、线程dump文件、GC日志等。通过虚拟机监控和诊断工具可以帮忙我们快速获取、分析需要的数据,进而提高问题解决速度。可以使用图形化工具如:jconsole,jvisualvm,或者命令进行监控和诊断命令。 本文将介绍虚拟机常用监控和问题诊断命令工具的使用方法,主要包含以下工具:
jps | 显示系统中所有Hotspot虚拟机进程 |
jstat | 收集Hotspot虚拟机各方面运行数据 |
jstack | 显示虚拟机的线程栈信息 |
jinfo | 显示虚拟机的配置信息 |
jmap | 用于生成虚拟机的内存快照信息 |
- 命令介绍
1).jps 命令
JVM Process Status Tool,该命令用于列出正在运行的虚拟机进程,显示main类的名称和虚拟机进程id。该命令受当前用户的访问权限影响,比如linux下非root用户只列出当前用户启动的虚拟机进程。
命令格式:
jps [options] [hostid]
执行示例:
glassfish@0220:~$ jps -l 32214 sun.tools.jps.Jps 11850 com.sun.enterprise.glassfish.bootstrap.ASMain
常用参数:
-l | 输出主类全名 |
-v | 输出虚拟机进程启动的jvm参数 |
-m | 输出启动时传递给main函数的参数 |
2).jstack 命令
Stack Trace for Java,用于生成虚拟机当前的线程快照信息,包含每一条线程的堆栈信息。该命令通常用于定位线程停顿原因,当出现线程停顿时,可通过stack查看每个线程的堆栈信息,进而分析停顿原因。
命令格式:
jstack [ option ] pid
常用参数:
-l | 除堆栈外,显示锁的附加信息 |
-F | 当请求不被响应时,强制输出线程堆栈 |
-m | 混合模式,打印java和本地C++调用的堆栈信息 |
执行示例:
"Thread-11" #24 daemon prio=5 os_prio=0 tid=0x0000000001b55800 nid=0x2e67 waiting on condition [0x00007ff666bfc000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000e1b8ccb8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) "Thread-9" #21 daemon prio=5 os_prio=0 tid=0x0000000001b0a000 nid=0x2e64 waiting on condition [0x00007ff66c346000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000e1e1a310> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403) at com.sun.common.util.logging.LoggingOutputStream.log(LoggingOutputStream.java:144) at com.sun.common.util.logging.LoggingOutputStream$1.run(LoggingOutputStream.java:123) "Thread-8" #20 daemon prio=5 os_prio=0 tid=0x0000000001b08800 nid=0x2e63 waiting on condition [0x00007ff66c447000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000e1e0b4e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:403) at com.sun.common.util.logging.LoggingOutputStream.log(LoggingOutputStream.java:144) at com.sun.common.util.logging.LoggingOutputStream$1.run(LoggingOutputStream.java:123) "pool-1-thread-1" #18 daemon prio=5 os_prio=0 tid=0x0000000001af4800 nid=0x2e61 waiting on condition [0x00007ff66c649000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000000e1a12528> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) "Timer-0" #13 daemon prio=5 os_prio=0 tid=0x00007ff6844f7000 nid=0x2e5c in Object.wait() [0x00007ff66cdf8000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000e15087b0> (a java.util.TaskQueue) at java.lang.Object.wait(Object.java:502) at java.util.TimerThread.mainLoop(Timer.java:526) - locked <0x00000000e15087b0> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) "FelixDispatchQueue" #11 daemon prio=5 os_prio=0 tid=0x00007ff64400e800 nid=0x2e5a in Object.wait() [0x00007ff66e36a000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at org.apache.felix.framework.util.EventDispatcher.run(EventDispatcher.java:1063) - locked <0x00000000e0c8da80> (a java.util.ArrayList) at org.apache.felix.framework.util.EventDispatcher.access$000(EventDispatcher.java:54) at org.apache.felix.framework.util.EventDispatcher$1.run(EventDispatcher.java:101) at java.lang.Thread.run(Thread.java:745) "Service Thread" #7 daemon prio=9 os_prio=0 tid=0x00007ff6841ef000 nid=0x2e57 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007ff6841d2000 nid=0x2e56 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007ff6841d0000 nid=0x2e55 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007ff684135800 nid=0x2e54 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007ff684105000 nid=0x2e53 in Object.wait() [0x00007ff66eff6000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142) - locked <0x00000000e0c753b8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007ff684103000 nid=0x2e52 in Object.wait() [0x00007ff66f0f7000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157) - locked <0x00000000e048ac30> (a java.lang.ref.Reference$Lock) "VM Thread" os_prio=0 tid=0x00007ff6840fc000 nid=0x2e51 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007ff684023000 nid=0x2e4f runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007ff684025000 nid=0x2e50 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007ff6841f1800 nid=0x2e58 waiting on condition JNI global references: 298
3) jstat命令
JVM Statistics Monitoring Tool,用于监控各种运行状态信息的命令。在只有文本控制台的环境中(如企业中的生产环境),该工具非常有用。 可以用来显示系统中类装载、垃圾回收、运行期编译状况等运行数据。
命令格式:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
vmid表示虚拟机唯一标识符,如果是本地虚拟机进程,与LVMID一致,通常为本地虚拟机进程号。 interval表示查询间隔时间,count表示查询次数。如果省略interval和count参数,表示查询一次。
常用参数:
class | 类装载相关信息. |
compiler | JIT编译器编译过的方法、耗时等. |
gc | java堆信息和垃圾回收状况. |
gccapacity | 关注java堆各个区的最大和最小空间. |
gccause | 类似gcutil,额外输出导致上一次gc的原因. |
gcnew | 新生代gc状况. |
gcnewcapacity | 关注新生代gc使用的最大和最小空间. |
gcold | 老年代gc状况. |
gcoldcapacity | 关注老年代gc使用的最大和最小空间. |
gcpermcapacity | 关注持久代gc使用的最大和最小空间. |
gcutil | 关注已使用空间占总空间比例. |
printcompilation | 输出已经被JIT编译的方法. |
执行示例
glassfish@0220:~$ jstat -gcutil 11850 1000 3 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 66.10 96.76 84.62 86.22 77.39 6404 119.294 158 103.270 222.564 0.00 66.10 96.76 84.62 86.22 77.39 6404 119.294 158 103.270 222.564 0.00 66.10 97.15 84.62 86.22 77.39 6404 119.294 158 103.270 222.564
S0和S1表示Survivor0和Survivor1,E表示新生代Eden,O表示老年代Old,M表示元空间大小,以上各参数值表示已使用空间占比。ccs压缩类空间, YGC表示young gc次数,YGCT表示young gc总耗时。FGC表示Full gc次数,FGCT表示full gc总耗时。GCT表示所有gc总耗时时间。jdk8以前: P表示持久代Permanent
4) jinfo命令
Configuration Info for Java,用于查看和修改虚拟机的各项参数信息。
命令格式:
jinfo [ option ] pid
常用参数:
-flag name | 打印虚拟机该参数对应的值. |
-flag [+\-]name | 使该参数生效或失效. |
-flag name=value | 修改相应参数的值. |
-flags | 打印传给jvm的参数值. |
-sysprops | 打印System.getProperties()信息. |
5) jmap命令
Memory Map for Java,可以产生堆dump文件,查询堆和持久代的详细信息等。
命令格式:
jmap [ option ] pid
常用参数:
-dump | 生成堆dump文件,格式为: -dump:[live,]format=b,file=<filename> |
-heap | 显示java堆的详细信息,包括垃圾回收期、堆配置和分代信息等 |
-histo | 显示堆中对象的统计信息,包括类名称,对应的实例数量和总容量 |
-permstat | 统计持久代中各ClassLoader的统计信息。 |
示例:
jmap -dump:format=b,file=dump.tmp 11850 Dumping heap to /home/glassfish/dump.tmp ... Heap dump file created上面这个命令生成了dump.tmp这个dump文件。生成的dump文件可以使用Eclipse Memory Analyzer/jhat等工具进行分析
6) jhatk命令
Jvm Heap Analysis Tool, 与jmap一起使用
示例:
jhat dump.tmp Reading from dump.tmp... Dump file created Tue Jun 28 13:55:09 CST 2016
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.sun.tools.hat.internal.model.Snapshot.makeId(Snapshot.java:586) at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:166) at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:737) at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:484) at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:238) at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:92) at com.sun.tools.hat.Main.main(Main.java:159)
- 遇到的问题
Attaching to process ID 3538, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
解决方法:
1. echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
该方法在下次重启前有效。
2. 永久有效方法
sudo vi /etc/sysctl.d/10-ptrace.conf
编辑下面这行:
kernel.yama.ptrace_scope = 1
修改为:
kernel.yama.ptrace_scope = 0
重启系统,使修改生效。
该bug详细信息请参考官方文档: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7050524
相关推荐
### JVM问题诊断常用命令详解 在Java开发与运维过程中,针对JVM(Java虚拟机)进行性能调优、故障排查是非常重要的环节。本文将详细介绍三种常用的JVM问题诊断工具:`jinfo`、`jmap` 和 `jstack` 的功能、用法以及...
### 美团JVM问题定位和排错 #### 背景 在现代软件开发中,Java虚拟机(JVM)作为运行Java程序的基础平台,对于任何使用Java语言进行开发的服务都至关重要。然而,在实际运行过程中,由于复杂的运行环境和技术栈的...
本系列课程从JVM基础到高级实战,老师手把手教你如何进行JVM...1.3JVM参数设置思路1.4JVM调优常用指令说明 第七节:JVM项目实战 1.1案例背景 1.2排查步骤 1.3.arthas 1.3.1.arthas简介 1.3.2.arthas实战 1.3总结
#### 三、常用命令及应用场景 ##### 1. **top** - **命令格式**:`top` - **功能**:显示系统中的进程列表,可以查看每个进程的CPU使用率、内存使用率等信息。 - **应用场景**: - 监控系统资源使用情况。 - ...
在“一图掌握Artha-常用命令汇总”中,我们可以学习到Arthas的核心功能和常用命令,以便在实际开发中更好地利用这个强大的工具。 1. **启动Arthas** 首先,你需要下载并安装Arthas,然后通过命令行启动Arthas。...
### JVM相关的常见面试问题知识点汇总 #### 1. 什么是JVM? - **定义**: JVM全称Java Virtual Machine,即Java虚拟机,是Java程序运行的底层平台。 - **作用**: 它为Java应用程序提供了一个运行环境,可以执行Java...
3:JVM内存调优:JVM参数【标准参数、-X参数、-XX参数等】+常用命令【jps、jinfo、jstat、jstack、jmap】+常用工具【jconsole、jvisualvm、Arthas、MAT】+性能优化及总结+高并发场景分析+JVM性能优化指南。
性能测试常用命令 性能测试是软件测试的一个重要方面,涉及到对系统的整体性能进行评估和优化。下面将从硬件信息、中间件、监控Linux服务器、监控和诊断JVM、其它命令五个方面总结常用的性能测试命令。 一、硬件...
本文将详细介绍一些常用的JVM参数设置,这些参数适用于线上关键业务系统,并且具有较高的通用性。 #### 二、学习资源推荐 1. **开源项目启动脚本**:参考成熟的开源项目如ElasticSearch和Cassandra的启动脚本可以...
因此,掌握一些常用的JVM性能调优和监控工具对于Java开发者来说至关重要。本文将详细介绍几种常见的JVM性能调优工具,并通过实际案例帮助读者更好地理解和应用这些工具。 #### 一、jps (Java Virtual Machine ...
常用的JVM启动参数有哪些? - **-Xms**:设置初始堆大小。 - **-Xmx**:设置最大堆大小。 - **-XX:+UseG1GC**:启用G1垃圾收集器。 - **-XX:+PrintGCDetails**:打印详细的GC信息。 #### 6.1 设置堆内存-XMX应该...
通过以上内容的学习,我们可以了解到DOS命令的基本使用方法,以及Linux系统的基础知识和常用命令。此外,对于大数据领域的学习者来说,掌握分布式系统的基本原理以及Hadoop、Storm、Spark等关键技术框架是非常重要的...
通过`jmap -dump:format=b,file=heap.hprof <pid>`命令,我们可以将JVM的堆内存快照导出为一个二进制文件,用于后续的内存分析,找出可能的内存泄漏问题。此外,`jmap -histo:live <pid>`可以列出活动对象的数量和...
Git常用命令面试题60道 Java并发编程最全面试题123道 Java基础面试题 91道 Java集合面试题 52道 Java虚拟机(JVM)面试题 51道 Java异常面试题 33道 JVM常见面试题解析 Kafka知识汇总 18道 大数据架构.vsdx 大数据...
【Arthas命令总结】 Arthas是一款由阿里巴巴开源的Java诊断工具,它提供了一组命令行工具,帮助开发者在不重启应用的情况下进行问题定位、性能优化和动态代码修改。Arthas支持Spring Boot、Spring Cloud等框架,...
【标题】"Java中常用的英语单词汇总共22页.pdf.zip" 提供的是关于Java编程语言中常见英文词汇的集合,这份文档可能是为了帮助Java开发者更好地理解和记忆在编程过程中经常遇到的专业术语。Java是一种广泛使用的面向...
这是一个关于软件测试面试题目的列表,收集了关于测试理论,自动化测试,性能测试以及其他一些软件测试相关的面试题目。...列出超过10个Linux常用的命令以及其作用? 进程和线程是什么?它们有什么区别和联系?
本文将详细讲述Java常用软件的安装、配置流程以及环境变量的配置方法。 首先,我们需要了解Java编码工具Eclipse。Eclipse是一个开放源代码的集成开发环境(IDE),支持多种编程语言的开发,包括Java。Eclipse的安装...
这些知识点主要围绕着JDK(Java开发工具包)中的基本命令以及如何使用这些命令进行Java程序的编译和运行。 ### 关键知识点 #### 1. JDK简介 - **定义**:JDK是Java Development Kit的缩写,即Java开发工具包。它是...
在Java开发过程中,掌握一些常用的命令行指令是十分必要的,这些指令可以帮助开发者高效地进行编译、运行、调试以及管理项目。"Java开发常用指令全集.7z"中的文档"Java开发常用指令全集.doc"很可能是对这些重要指令...