为什么这个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: -  (a java.util.concurrent.locks.ReentrantLock$NonfairSync) 

没有这个选项,就无法弄清楚在验尸中持有此锁的线程。 为什么此选项不是默认选项? 是否存在一些非明显的性能或稳定性惩罚? 当我搜索到对此的讨论时,什么都没有出现。

好吧,我的猜测是它不稳定,或者JVM维护者(Sun-now-Oracle)根本不想将其维护为受支持的function。 您可以通过-XX:前缀简单地告诉它:

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

– 来自Java HotSpot VM选项

此外,该页面还可以通过JDK管理界面动态启用或禁用该选项,因此您可以根据需要通过MXBean启用它。

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

最后, jstack Stack Trace工具可以随时执行相同的function,而无需一直启用它。

我问Oracle(我的雇主有一个支持联系人),答案基本上是该选项可以安全使用,并且默认情况下禁用了许多纯诊断function,这是其中一个选项。 IMO,如果诊断function安全稳定且不会引入性能损失,则默认情况下应该启用它。 看起来这不是(当时)Sun和(现在)Oracle的观点。

因为,只有ReentrantLocks知道它们与哪些线程相关。 要获取有关此方法的运行时实现的此信息,请通过堆查找所有锁及其线程。