Control+Break在JVM中的处理
2.19 Control + Break 处理程序
在 Oracle Solaris 或 Linux 操作系统上, 在应用程序控制台 (标准输入) 中按下Ctrl控制键和反斜线 (\
) 键的组合会导致 Java 热点 VM 将线程转储打印到应用程序的标准输出。在 Windows 上, 等效的键序列是控件和中断键。这些组合键的一般术语是Control + Break 处理程序。
在 Oracle Solaris 和 Linux 操作系统上, 如果 Java 进程收到退出信号, 则会打印一个线程转储。因此, kill -QUIT pid
命令会导致带有 ID pid
的进程将线程转储打印到标准输出。
以下各节描述由Control + Break 处理程序跟踪的数据:
线程转储
检测死锁
堆摘要
2.19.1线程转储
线程转储由线程堆栈 (包括线程状态) 组成, 用于虚拟机中的所有 Java 线程。线程转储不会终止应用程序: 在打印线程信息之后, 它将继续。
示例 2-35阐释了一个线程转储。
JVM 中所有 Java 线程的示例2-35 线程转储
Full thread dump Java HotSpot(TM) Client VM (1.6.0-rc-b100 mixed mode): "DestroyJavaVM" prio=10 tid=0x00030400 nid=0x2 waiting on condition [0x00000000..0xfe77fbf0] java.lang.Thread.State: RUNNABLE "Thread2" prio=10 tid=0x000d7c00 nid=0xb waiting for monitor entry [0xf36ff000..0xf36ff8c0] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a938> (a java.lang.String) - locked <0xf819a970> (a java.lang.String) "Thread1" prio=10 tid=0x000d6c00 nid=0xa waiting for monitor entry [0xf37ff000..0xf37ffbc0] java.lang.Thread.State: BLOCKED (on object monitor) at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a970> (a java.lang.String) - locked <0xf819a938> (a java.lang.String) "Low Memory Detector" daemon prio=10 tid=0x000c7800 nid=0x8 runnable [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "CompilerThread0" daemon prio=10 tid=0x000c5400 nid=0x7 waiting on condition [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio=10 tid=0x000c4400 nid=0x6 waiting on condition [0x00000000..0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=10 tid=0x000b2800 nid=0x5 in Object.wait() [0xf3f7f000..0xf3f7f9c0] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116) - locked <0xf4000b40> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "Reference Handler" daemon prio=10 tid=0x000ae000 nid=0x4 in Object.wait() [0xfe57f000..0xfe57f940] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0xf4000a40> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:485) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) - locked <0xf4000a40> (a java.lang.ref.Reference$Lock) "VM Thread" prio=10 tid=0x000ab000 nid=0x3 runnable "VM Periodic Task Thread" prio=10 tid=0x000c8c00 nid=0x9 waiting on condition
输出由一个由空行分隔的多个线程项组成。java 线程 (能够执行 java 语言代码的线程) 首先打印出来, 后面是有关 VM 内部线程的信息。每个线程项都由标题行和线程堆栈跟踪组成。
标题行包含有关线程的以下信息:
线程名称
指示线程是否为守护进程线程
线程优先级 (prio)
线程 ID (tid), 它是内存中线程结构的地址
本机线程的 ID (nid)
线程状态, 指示线程在线程转储时所做的操作。有关详细信息, 请参见表 2-6 。
地址范围, 它给出了线程的有效堆栈区域的估计值。
2.19.2检测死锁
除了线程堆栈之外, 控件 + 中断处理程序还执行死锁检测算法。如果检测到任何死锁, 则控制 + 中断处理程序 (如示例 2-36所示) 在每个已死锁线程上的线程转储之后打印附加信息。
示例2-36 死锁线程的附加信息
Found one Java-level deadlock: ============================= "Thread2": waiting to lock monitor 0x000af330 (object 0xf819a938, a java.lang.String), which is held by "Thread1" "Thread1": waiting to lock monitor 0x000af398 (object 0xf819a970, a java.lang.String), which is held by "Thread2" Java stack information for the threads listed above: =================================================== "Thread2": at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a938> (a java.lang.String) - locked <0xf819a970> (a java.lang.String) "Thread1": at Deadlock$DeadlockMakerThread.run(Deadlock.java:32) - waiting to lock <0xf819a970> (a java.lang.String) - locked <0xf819a938> (a java.lang.String) Found 1 deadlock.
如果设置了 JVM 标志-XX:+PrintConcurrentLocks
, 则Control + Break 处理程序还将打印每个线程拥有的并发锁的列表。
2.19.3堆摘要
Control + Break 处理程序也会打印堆摘要.示例 2-37显示不同的世代 (堆的区域), 大小、使用量和地址范围。如果同时使用工具 (如pmap ) 检查进程, 则地址范围尤其有用。.
示例2-37 堆摘要
Heap def new generation total 1152K, used 435K [0x22960000, 0x22a90000, 0x22e40000 ) eden space 1088K, 40% used [0x22960000, 0x229ccd40, 0x22a70000) from space 64K, 0% used [0x22a70000, 0x22a70000, 0x22a80000) to space 64K, 0% used [0x22a80000, 0x22a80000, 0x22a90000) tenured generation total 13728K, used 6971K [0x22e40000, 0x23ba8000, 0x269600 00) the space 13728K, 50% used [0x22e40000, 0x2350ecb0, 0x2350ee00, 0x23ba8000) compacting perm gen total 12288K, used 1417K [0x26960000, 0x27560000, 0x2a9600 00) the space 12288K, 11% used [0x26960000, 0x26ac24f8, 0x26ac2600, 0x27560000) ro space 8192K, 62% used [0x2a960000, 0x2ae5ba98, 0x2ae5bc00, 0x2b160000) rw space 12288K, 52% used [0x2b160000, 0x2b79e410, 0x2b79e600, 0x2bd60000)
如果设置了 JVM 标志-XX:+PrintClassHistogram
, 则Control + Break 处理程序将生成堆直方图。