Obtendo os parâmetros de uma JVM em execução

92

Existe uma maneira de obter os parâmetros de uma JVM em execução? Existe uma ferramenta de linha de comando como jstat que leva como entrada o pid da JVM e retorna seus parâmetros iniciais? Estou particularmente interessado nos valores -Xmx e -Xms que foram fornecidos ao iniciar o JVM. Obrigado.

Edit : Para esclarecer minhas restrições. A JVM que gostaríamos de verificar está sendo executada em um servidor de produção. É por isso que preferimos o mínimo de interrupção. Podemos monitorar a JVM usando jstat e, portanto, esperamos que haja uma solução simples semelhante para acessar os parâmetros.

Edit : também tentamos obter os parâmetros usando jvisualvm. Mas, para conectar a um jvm remoto, precisamos executar jstatd e modificar as configurações de segurança da JVM, que descobrimos ser muito perturbadoras e arriscadas em um servidor de produção.

HH
fonte
Você pode encontrar uma ferramenta lá: JDK Tools and Utilities
Guillaume Husta

Respostas:

148

Você pode usar jps como

jps -lvm

imprime algo como

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
Peter Lawrey
fonte
6
Funciona como um encanto. Também descobri a ferramenta jinfo no jdk que tem uma função semelhante
HH
2
Observe que a saída de jps -lvmpode ser enganosa. Sempre verifique com jinfo ou outra ferramenta. O problema pode ser se "-XX" for passado como o argumento normal do programa e ignorado pela JVM. Este é o caso se você usar em java -jar my.jar -Xmx3gvez dejava -Xmx3g -jar my.jar
Juraj Martinka
39

Estou adicionando esta nova resposta porque de acordo com a documentação do JDK8 , o jcmd é a abordagem sugerida agora.

É sugerido usar o utilitário mais recente, jcmd em vez dos utilitários jstack, jinfo e jmap anteriores para diagnósticos aprimorados e sobrecarga de desempenho reduzida.

Abaixo estão os comandos para obter as propriedades / sinalizadores que você deseja.

jcmd pid VM.system_properties
jcmd pid VM.flags

Precisamos de pid, para isso use jcmd -l, como abaixo

username@users-Air:~/javacode$ jcmd -l 
11441 Test 
6294 Test 
29197 jdk.jcmd/sun.tools.jcmd.JCmd -l 

Agora é hora de usar esses pids para obter as propriedades / sinalizadores que você deseja

Comando: 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

Comando: jcmd 11441 VM.flags output:

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 

Para obter mais instruções de uso do jcmd, consulte minha postagem no blog

Vipin
fonte
Não foi possível encontrar nenhum processo correspondente: 'pid'
Ch Vas
1
pid deve ser substituído pelo id do processo java, o Linux geralmente é obtido por “ps -ef | grep jdk ”, se você ver vários processos assim, faça uma nova pergunta ou tente pesquisar no Google
Vipin
24

No Linux:

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

No Mac OSX:

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

No Windows:

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

Fonte: https://www.mkyong.com/java/find-out-your-java-heap-memory-size/

Diego López
fonte
22

Alternativamente, você pode usar jinfo

jinfo -flags <vmid> 
jinfo -sysprops <vmid>
Jarek Przygódzki
fonte
3
Este utilitário não tem suporte e pode ou não estar disponível em versões futuras do JDK.
GoYun.Info
-flagsopção não existe no servidor VM OpenJDK de 64 bits (compilação 1.8.0_111-internal-alpine-r0-b14) ( java:8u111-jdk-alpineimagem atual do Docker)
Anthony O.
Escrevi esta resposta com Java 6/7 em mente. Além disso, o jinfo não é confiável, mas flagsfunciona com a imagem oficial do Docker java baseada no Debian Jessie docker run --rm -it java:8u111-jdk java -version && jinfo -h
Jarek Przygódzki
16

Se você pode fazer isso em java, tente:

RuntimeMXBean

ManagementFactory

Exemplo:

RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
for (String arg : jvmArgs) {
    System.out.println(arg);
}
lukastymo
fonte
1
Só fornecerá valores se for aprovado, portanto, sem configurações padrão.
Behe
8

JConsole pode fazer isso. Além disso, você pode usar uma ferramenta jvisualVM poderosa, que também está incluída no JDK desde 1.6.0.8.

Vladimir Ivanov
fonte
3

No Linux, você pode executar este comando e ver o resultado:

ps aux | grep "java"
Etienne
fonte
Minha empresa usa Red Hat Linux e eu tenho acesso muito limitado ao sistema. ps aux | O comando grep "java" lista todos os comandos java com seus argumentos jvm e podemos até mesmo fazer o grep do argumento jvm exato, se necessário. Isso é muito útil no caso de quaisquer outras ferramentas como jps, jcmd etc não estarem disponíveis / acessíveis.
AGan
2

O Windows 10 ou o Windows Server 2016 fornecem essas informações em seu gerenciador de tarefas padrão. Um caso raro de produção, mas se a JVM de destino estiver em execução no Windows, a maneira mais simples de ver seus parâmetros é pressionar Ctrl + Alt + Delete, escolher a guia Processos e adicionar a coluna Linha de comando (clicando com o botão direito do mouse em qualquer cabeçalho de coluna existente).

Khomyshynets romanos
fonte
1

Se você estiver interessado em obter os parâmetros JVM de um processo java em execução, basta executar kill -3 java-pid. Você obterá um arquivo de dump principal no qual poderá encontrar os parâmetros jvm usados ​​ao iniciar o aplicativo java.

Lambzee
fonte
0

Você pode usar o comando JConsole (ou qualquer outro cliente JMX) para acessar essas informações.

nfechner
fonte
0

Essa técnica se aplica a qualquer aplicativo Java em execução local ou remota.

  1. Inicie seu aplicativo Java.
  2. Execute JVisualVM encontrado em seu JDK (como C: \ Arquivos de programas \ Java \ jdk1.8.0_05 \ bin \ jvisualvm.exe).
  3. Quando esta ferramenta útil for iniciada, observe a lista de aplicativos Java em execução no nó da árvore "Local".
  4. Clique duas vezes em [seu aplicativo] (pid [n]).
  5. No lado direito haverá conteúdo de inspeção na guia para o aplicativo. No meio da guia Visão geral, você verá os argumentos JVM para o aplicativo.

O jvisualvm pode ser encontrado em qualquer JDK desde o JDK 6 Atualização 7. O vídeo tutorial sobre o jvisualvm está aqui.

javajon
fonte
OP declarou explicitamente que jvisualvm não era uma opção.
Olivier Gérardin
0

_JAVA_OPTIONS é uma variável env que pode ser expandida.

echo $_JAVA_OPTIONS
z atef
fonte