【问题标题】:Getting the parameters of a running JVM获取正在运行的 JVM 的参数
【发布时间】:2011-07-16 02:04:43
【问题描述】:

有没有办法获取正在运行的JVM的参数?

是否有像 jstat 这样的命令行工具,它将 JVM 的 PID 作为输入并返回其起始参数?我对启动 JVM 时给出的 -Xmx-Xms 值特别感兴趣。

为了澄清我对 JVM 的限制,我们想检查它是否在生产服务器上运行。这就是为什么我们更喜欢最小的干扰。我们能够使用 jstat 监控 JVM,因此我们希望有一个类似的简单解决方案来访问参数。

我们还尝试使用 jvisualvm 获取参数。但是为了连接到远程 jvm,我们需要运行 jstatd 并修改 JVM 的安全设置,我们发现这在生产服务器上非常具有破坏性和风险。

【问题讨论】:

标签: java jvm


【解决方案1】:

你可以像这样使用 jps:

jps -lvm

它会打印如下内容:

4050 com.intellij.idea.Main -Xms128m -Xmx512m -XX:MaxPermSize=250m -ea -Xbootclasspath/a:../lib/boot.jar -Djb.restart.code=88
4667 sun.tools.jps.Jps -lvm -Dapplication.home=/opt/java/jdk1.6.0_22 -Xms8m

【讨论】:

  • 像魅力一样工作。我还在jdk中发现了jinfo工具,它有类似的功能
  • 请注意jps -lvm 的输出可能具有误导性。始终使用 jinfo 或其他工具仔细检查。问题可能是如果“-XX”像普通程序参数一样被传递并被 JVM 忽略。如果您使用java -jar my.jar -Xmx3g 而不是java -Xmx3g -jar my.jar,就会出现这种情况
【解决方案2】:

根据JDK 8 documentation jcmd 是建议的方法。

建议使用最新的实用程序 jcmd 而不是 以前用于增强诊断的 jstack、jinfo 和 jmap 实用程序 并减少性能开销。

以下是获取所需属性/标志的命令。

jcmd pid VM.system_properties
jcmd pid VM.flags

我们需要PID。为此,请使用jcmd -l,如下所示

cd ~/javacode
jcmd -l

11441 Test
6294 Test
29197 jdk.jcmd/sun.tools.jcmd.JCmd -l

现在是时候使用这些 PID 来获取您想要的属性/标志了。

命令:jcmd 11441 VM.system_properties

11441:
#Tue Oct 17 12:44:50 IST 2017
gopherProxySet=false
awt.toolkit=sun.lwawt.macosx.LWCToolkit
file.encoding.pkg=sun.io
java.specification.version=9
sun.cpu.isalist=
sun.jnu.encoding=UTF-8
java.class.path=.
java.vm.vendor=Oracle Corporation
sun.arch.data.model=64
java.vendor.url=http\://java.oracle.com/
user.timezone=Asia/Kolkata
java.vm.specification.version=9
os.name=Mac OS X
sun.java.launcher=SUN_STANDARD
user.country=US
sun.boot.library.path=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/lib
sun.java.command=Test
http.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
jdk.debug=release
sun.cpu.endian=little
user.home=/Users/XXXX
user.language=en
java.specification.vendor=Oracle Corporation
java.home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
file.separator=/
java.vm.compressedOopsMode=Zero based
line.separator=\n
java.specification.name=Java Platform API Specification
java.vm.specification.vendor=Oracle Corporation
java.awt.graphicsenv=sun.awt.CGraphicsEnvironment
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
ftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
java.runtime.version=9+181
user.name=XXXX
path.separator=\:
os.version=10.12.6
java.runtime.name=Java(TM) SE Runtime Environment
file.encoding=UTF-8
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vendor.url.bug=http\://bugreport.java.com/bugreport/
java.io.tmpdir=/var/folders/dm/gd6lc90d0hg220lzw_m7krr00000gn/T/
java.version=9
user.dir=/Users/XXXX/javacode
os.arch=x86_64
java.vm.specification.name=Java Virtual Machine Specification
java.awt.printerjob=sun.lwawt.macosx.CPrinterJob
sun.os.patch.level=unknown
MyParam=2
java.library.path=/Users/XXXX/Library/Java/Extensions\:/Library/Java/Extensions\:/Network/Library/Java/Extensions\:/System/Library/Java/Extensions\:/usr/lib/java\:.
java.vm.info=mixed mode
java.vendor=Oracle Corporation
java.vm.version=9+181
sun.io.unicode.encoding=UnicodeBig
java.class.version=53.0
socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16

命令:jcmd 11441 VM.flags 输出:

11441:
-XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1ConcRefinementThreads=4 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=67108864 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576 -XX:NonNMethodCodeHeapSize=5830092 -XX:NonProfiledCodeHeapSize=122914074 -XX:ProfiledCodeHeapSize=122914074 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:-UseAOT -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC

更多jcmd的使用说明请见my blog post

【讨论】:

  • 找不到任何匹配的进程:'pid'
  • pid要替换成java进程id,Linux操作系统一般我们通过“ps -ef | grep jdk”,如果您看到多个进程,请提出一个新问题或尝试谷歌
【解决方案3】:

在 Linux 上:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

在 Mac OS X 上:

java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'

在 Windows 上:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

来源:Find out your Java heap memory size

【讨论】:

  • 这并没有解决获取正在运行进程的 JVM 标志的问题
【解决方案4】:

或者,您可以使用jinfo

jinfo -flags <vmid> 
jinfo -sysprops <vmid>

【讨论】:

  • 此实用程序不受支持,可能会或可能不会在 JDK 的未来版本中可用。
  • -flags 选项在 OpenJDK 64 位服务器 VM(内部版本 1.8.0_111-internal-alpine-r0-b14)中不存在(当前 java:8u111-jdk-alpine Docker 映像)
  • 我写这个答案时考虑到了 Java 6/7。除此之外 jinfo 是不可靠的,但 flags 可以与基于 Debian Jessie docker run --rm -it java:8u111-jdk java -version &amp;&amp; jinfo -h 的官方 Docker java 映像一起使用
  • 也许是时候更新答案了?
【解决方案5】:

如果您可以在 Java 中执行此操作,请尝试:

RuntimeMXBean

ManagementFactory

示例:

RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
for (String arg : jvmArgs) {
    System.out.println(arg);
}

【讨论】:

  • 只有通过了才会提供值,因此没有默认设置。
【解决方案6】:

JConsole 可以做到。您还可以使用功能强大的Java VisualVM 工具,该工具自 1.6.0.8 起也包含在 JDK 中。

【讨论】:

    【解决方案7】:

    在 Linux 上,您可以运行此命令并查看结果:

    ps aux | grep "java"
    

    【讨论】:

    • 我的公司使用 Red Hat Linux,我对系统的访问权限非常有限。 ps辅助| grep "java" 命令列出所有 java 命令及其 jvm 参数,如果需要,我们甚至可以 grep 确切的 jvm 参数。这在 jps、jcmd 等任何其他工具不可用/不可访问的情况下非常有用。
    【解决方案8】:

    Windows 10 或 Windows Server 2016 在其标准 Task Manager 中提供此类信息。

    这在生产环境中很少见,但如果目标 JVM 在 Windows 上运行,查看其参数的最简单方法是按 Ctrl + Alt + 删除,选择进程选项卡并添加命令行列(通过在任何现有列标题上单击鼠标右键)。

    【讨论】:

      【解决方案9】:

      如果您有兴趣获取正在运行的 Java 进程的 JVM 参数,那么只需执行 kill -3 java-pid

      您将获得一个core dump 文件,您可以在其中找到启动 Java 应用程序时使用的 JVM 参数。

      【讨论】:

        【解决方案10】:

        您可以使用 JConsole 命令(或任何其他 JMX 客户端)来访问该信息。

        【讨论】:

          【解决方案11】:

          _JAVA_OPTIONS是一个可以扩展的环境变量:

          echo $_JAVA_OPTIONS
          

          【讨论】:

            【解决方案12】:

            此技术适用于任何本地或远程运行的 Java 应用程序。

            1. 启动您的 Java 应用程序。
            2. 运行在你的JDK中找到的Java VisualVM(例如C:\Program 文件\Java\jdk1.8.0_05\bin\jvisualvm.exe)。
            3. 当这个有用的工具启动时,请查看正在运行的 Java 应用程序列表 “本地”树节点。
            4. 双击 [您的应用程序] (pid [n])。
            5. 在右侧,选项卡中将有检查内容 应用。在 Overview 选项卡的中间,您将看到应用程序的 JVM 参数。

            Java VisualVM 可以在自 JDK 6 Update 7 以来的任何 JDK 中找到。有关 Java VisualVM 的视频教程是 here

            【讨论】:

            • OP 明确声明 jvisualvm 不是一个选项。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-17
            • 1970-01-01
            • 2016-05-24
            • 2010-12-25
            • 1970-01-01
            • 2010-09-18
            相关资源
            最近更新 更多