为什么Hotspot JVM选项不是默认的?- xx: + PrintConcurrentLocks



默认情况下,对于Hotspot, CTRL-Break线程转储不会列出持有java.lang.concurrent锁的线程。我知道,有了这些锁,Hotspot无法获得关于锁在哪个堆栈帧被获取的信息。如果您添加了JVM选项-XX:+PrintConcurrentLocks,那么CTRL-Break堆栈转储将列出(在线程的堆栈跟踪之后)该帧持有的所有并发锁。例如:

"D-Java-5-Lock" prio=6 tid=0x00000000069a1800 nid=0x196c runnable [0x000000000770f000]
   java.lang.Thread.State: RUNNABLE
      at com.Tester.longDelay(Tester.java:41)
      at com.Tester$D.run(Tester.java:88)
   Locked ownable synchronizers:
      - <0x00000007d6030898> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

如果没有这个选项,就不可能在事后分析中找出哪个线程持有这个锁。为什么这个选项不是默认的?是否存在一些不明显的性能或稳定性损失?当我搜索关于这个的讨论时,什么也没有出现。

我问了Oracle(我的雇主有一个支持联系人),答案基本上是这个选项可以安全使用,并且默认情况下许多纯粹的诊断功能是禁用的,这是其中一个选项。在我看来,如果一个诊断特性是安全和稳定的,并且不会带来性能损失,那么它就应该在默认情况下开启。(当时)Sun公司和(现在)Oracle公司的情况似乎并非如此。

嗯,我的猜测是它不稳定,或者JVM维护者(Sun-now-Oracle)根本不想把它作为一个受支持的特性来维护。您可以通过-XX:前缀来判断:

使用-XX指定的选项不稳定,不建议随意使用。这些选项如有更改,恕不另行通知。

- from Java HotSpot VM Options

同样在该页中,该选项可以通过JDK管理接口动态启用或禁用,因此如果需要,您可以通过MXBean启用它。

标记为可管理的标志可以通过JDK管理接口(com.sun.management)动态写入。HotSpotDiagnosticMXBean API),也可以通过JConsole。在监视和管理Java SE 6平台应用程序中,图3显示了一个示例。还可以通过jinfo -flag设置可管理的标志。

最后,jstack Stack Trace工具可以在任何时候执行相同的功能,而不需要一直启用它。

因为只有ReentrantLocks知道它们与哪些线程相关。要在运行时获得此信息,该方法的实现应该遍历堆以查找所有锁及其线程。

最新更新