获取正在运行的JVM的参数


90

有没有办法获取正在运行的JVM的参数?是否有像jstat这样的命令行工具将JVM的pid作为输入并返回其启动参数?我对启动JVM时给出的-Xmx和-Xms值特别感兴趣。谢谢。

编辑:澄清我的约束。我们要检查的JVM正在生产服务器上运行。因此,我们更喜欢最小的干扰。我们能够使用jstat监视JVM,因此我们希望有一个类似的简单解决方案来访问参数。

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


您可以在此处找到一个工具:JDK工具和实用程序
Guillaume Husta

Answers:


145

你可以像这样使用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

6
奇迹般有效。我还在jdk中发现了具有类似功能的jinfo工具
HH

2
请注意,的输出jps -lvm可能会产生误导。始终使用jinfo或其他工具仔细检查。问题可能出在是否像常规程序参数一样传递了“ -XX”并且被JVM忽略了。这样的话,如果你使用java -jar my.jar -Xmx3g的不是java -Xmx3g -jar my.jar
尤拉伊Martinka

36

我要添加这个新答案,因为根据JDK8文档,现在建议使用jcmd方法。

建议使用最新的实用程序jcmd代替以前的jstack,jinfo和jmap实用程序,以增强诊断功能并降低性能开销。

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

jcmd pid VM.system_properties
jcmd pid VM.flags

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

username@users-Air:~/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用法的更多说明,请参阅我的博客文章


“的pid”:找不到任何匹配的过程
章沃什

1
pid应该用java进程ID代替,Linux os通常我们通过“ ps -ef | grep jdk”,如果您由此看到多个进程,则提出一个新问题或尝试用Google搜索
Vipin


21

或者,您可以使用jinfo

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

3
此实用程序不受支持,在JDK的将来版本中可能可用,也可能不可用。
GoYun.Info

-flags选项在OpenJDK 64位服务器VM(内部版本1.8.0_111-internal-alpine-r0-b14)(当前java:8u111-jdk-alpineDocker映像)中不存在
Anthony

我在编写此答案时就牢记Java 6/7。除此之外,jinfo是不可靠的,但flags可以与基于Debian Jessie的官方Docker java映像一起使用 docker run --rm -it java:8u111-jdk java -version && jinfo -h
JarekPrzygódzki,

15

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

运行时MXBean

管理工厂

例:

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

1
如果通过,将仅提供值,因此没有默认设置。
Behe 2016年


2

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

ps aux | grep "java"

我的公司使用Red Hat Linux,而我对该系统的访问非常有限。ps aux | grep“ java”命令列出了所有带有jvm参数的java命令,如果需要,我们甚至可以grep确切的jvm参数。万一其他任何工具(例如jps,jcmd等)不可用/不可访问,这真的很有用。
AGan

1

Windows 10或Windows Server 2016在其标准任务管理器中提供了此类信息。在生产中很少见,但如果目标JVM在Windows上运行,则查看其参数的最简单方法是按Ctrl + Alt + Delete,选择“进程”选项卡并添加“命令行”列(通过单击上的鼠标右键)任何现有的列标题)。


1

如果您有兴趣获取正在运行的Java进程的JVM参数,则只需执行kill -3 java-pid。您将获得一个核心转储文件,您可以在其中找到启动Java应用程序时使用的jvm参数。


0

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


0

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

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

从JDK 6 Update 7开始,可以在任何JDK中找到jvisualvm 有关jvisualvm的视频教​​程,请参见此处。


OP明确指出jvisualvm不是一个选择。
OlivierGérardin

0

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

echo $_JAVA_OPTIONS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.