在最近的几篇博客中(特别是在对Java EE 7性能调优和优化以及WildFly性能调优的书的评论中),我引用了自己过去在某些Oracle JDK命令行工具上的博客文章。 令我震惊的是,我从来没有专门解决过漂亮的jinfo工具,这篇文章旨在纠正这种令人不安的情况。 我怀疑我以前选择不写jinfo的原因包括我在VisualVM中讨论的与jinfo相关的限制:jinfo和So Much More 。
在我的机器上运行的Java SE 8版本的jinfo中,解决了我在“ 获取JVM运行时信息”一文中讨论的Windows上jinfo的主要限制。 特别是,我在-flags
文章中指出,当时Windows版本的jinfo
不支持-flags
选项。 正如下一个屏幕快照所证明的,情况已不再如此(请注意使用jps获取Java进程ID以指示jinfo
进行查询)。
如上面的屏幕快照所示, jinfo -flags
命令和option显示了标志,这些标志是要监视的Java进程的显式指定的JVM选项。
如果我想了解其他隐式(自动)有效的JVM标志,则可以运行java -XX:+ PrintFlagsFinal来查看所有默认的JVM选项。 然后,我可以针对正在运行的JVM进程查询其中的任何一个,以查明该特定JVM使用的是什么(相同的默认值或覆盖的不同值)。 下一个屏幕快照演示了如何通过运行java -XX:+PrintFlagsFinal
提供一小部分输出。
假设我在上面的输出中注意到一个名为PrintHeapAtGC的标志,并想知道它是否在我的特定Java应用程序中设置( -XX:+PrintHeapAtGC
表示已设置, -XX:-PrintHeapAtGC
表示未设置)。 我可以让jinfo
告诉我它的设置是什么(请注意,在这种情况下,我选择使用jcmd而不是jps来确定Java进程ID):
由于冒号后和“ PrintHeapAtGC”之前的减号(-)而不是加号(+),我们知道对于具有指定ID的Java进程已将其关闭。 事实证明,jinfo的作用不仅仅让我们看。 这也让我们感动。 下一个屏幕快照显示了使用jinfo
更改此选项。
如上一个屏幕快照所示,我可以通过使用相同的命令查看标志的设置来关闭和打开布尔样式的JVM选项,但是在标志名的前面加上加号(+)将其打开或加减。签署(-)将其关闭。 在刚刚显示的示例中,我关闭了PrintGCDateStamps
,再次将其重新打开,并在这些更改之间监视其设置。 并非所有的JVM选项都是布尔条件。 在这些情况下,通过将等号(=)和标志值后面的新值串联起来,为它们分配新值。 同样重要的是要注意目标JVM(您试图窥视并接触jinfo
的目标JVM将不允许您更改其所有JVM选项设置)。 在这种情况下,您可能会看到堆栈跟踪,并显示消息“目标VM中的命令失败”。
除了显示当前正在运行的JVM的选项并允许对其中一些选项进行更改之外, jinfo
还允许您将该JVM使用的系统属性视为名称/值对。 在下一个屏幕快照中对此进行了演示,并显示了输出的一小部分。
运行jinfo
的最简单方法可能就是仅提供所讨论的Java进程的PID以外的任何参数,并同时显示JVM选项(非默认值和命令行)和系统属性。 运行jinfo -help
提供简要的用法详细信息。 其他重要的详细信息可以在jinfo工具的Oracle文档中找到。 这些详细信息包括常见的提示(涉及这些工具时),提示该工具“是实验性的,不受支持”,并且“将来的JDK版本可能不可用”。 我们还警告我们Windows上的jinfo
需要dbgeng.dll或已安装的Windows调试工具的可用性。
尽管我之前在VisualVM:jinfo和更多内容以及获得JVM运行时信息一文中已经引用了方便的jinfo命令行工具,但它已经足够方便地证明了自己的帖子。 作为命令行工具,它具有与命令行工具通常相关的优点,例如相对轻量级,可以很好地与脚本一起使用以及在无头环境中工作。
翻译自: https://www.javacodegeeks.com/2014/08/jinfo-command-line-peeking-at-jvm-runtime-configuration.html