为什么这个Hotspot JVM选项不是默认选项?-XX:+PrintConcurrentLocks

7

默认情况下,使用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)

如果没有此选项,则无法在事后确定哪个线程持有此锁。为什么这个选项不是默认的呢?是否存在某些非明显的性能或稳定性惩罚?当我搜索以找到关于此的讨论时,没有任何结果。

3个回答

3

我向甲骨文公司(我的雇主有支持合同)提问,他们的答复基本上是这个选项是安全的,并且许多纯诊断功能默认情况下都被禁用,这是其中之一。在我看来,如果一个诊断功能是安全稳定的,不会引入性能损失,则应该默认开启。看起来,这并不是当时Sun和现在Oracle的看法。


add explanation. - egorlitvinenko

2

因为只有可重入锁知道它们所属的线程。要在运行时获取此信息,实现此方法应该遍历堆以查找所有锁及其线程。


2
我的猜测是它不稳定,或者JVM维护人员(现在是Sun-Oracle)只是不想将其作为支持的功能进行维护。您可以通过-XX:前缀简单地了解到这一点:

使用-XX指定的选项不稳定,并且不建议普通用户使用。这些选项可能会随时更改。

- 来自Java HotSpot VM Options

从该页面中还可以看出,该选项可以通过JDK管理接口动态启用或禁用,因此如果需要,可以通过MXBean启用它。

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

最后,jstack堆栈跟踪工具可以随时执行相同的功能,而无需始终启用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接