Não existe uma maneira independente de plataforma que possa garantir que funcione em todas as implementações da jvm.
ManagementFactory.getRuntimeMXBean().getName()parece a melhor solução (mais próxima). É curto e provavelmente funciona em todas as implementações de uso amplo.
No linux + windows, ele retorna um valor como 12345@hostname( 12345sendo o ID do processo). Cuidado, porém, de acordo com os documentos , não há garantias sobre esse valor:
Retorna o nome que representa a Java virtual machine em execução. A cadeia de nome retornada pode ser qualquer cadeia arbitrária e uma implementação da máquina virtual Java pode optar por incorporar informações úteis específicas da plataforma na cadeia de nome retornada. Cada máquina virtual em execução pode ter um nome diferente.
No Java 9, a nova API do processo pode ser usada para obter o ID do processo atual. Primeiro, você pega um identificador para o processo atual e, em seguida, consulta o PID:
muito bom, apenas verifiquei que ele funciona tanto no JRockit quanto nas JVMs do Hotspot.
Drupad Panchal
11
Solução agradável. Vou assumir que há um bom motivo para esse método (e outros da classe) não serem públicos e facilmente acessíveis, e estou curioso para saber o que é.
fragorl
2
A equipe Oracle Java anunciou que pretende ocultar todos os pacotes não-java (por exemplo, sun. *). Acredito que começando com o Java 10 (programado para 2018 - talvez Java 9). Se você possui uma implementação semelhante à acima, convém descobrir uma alternativa para que seu código não seja quebrado.
hfontanez
Não funciona para mim como o sol. * Os pacotes provavelmente estão removidos ou inacessíveis (o VMManagement não pode ser resolvido para um tipo).
Mike Stoddart
Devido à maneira como a reflexão funciona, o acesso ao sun.management. * Não é necessário. Basta executar o getDeclaredMethodno objeto retornado por jvm.get(runtime).
Andrew T Finnell
36
Tente Sigar . APIs muito extensas. Licença Apache 2.
Você teria muito mais votos positivos se explicasse como usar o SIGAR para isso #
Brad Mace
11
Link quebrado. Você dá um exemplo de como usar isso, mas existe alguma dependência para isso?
Jules
github.com/hyperic/sigar parece ser um local utilizável; isso também mostra que é um código nativo com ligações Java, o que pode torná-lo menos uma solução para muitos contextos.
Zastai 16/10/1918
26
O método a seguir tenta extrair o PID de java.lang.management.ManagementFactory:
privatestaticString getProcessId(finalString fallback){// Note: may fail in some JVM implementations// therefore fallback has to be provided// something like '<pid>@<hostname>', at least in SUN / Oracle JVMsfinalString jvmName =ManagementFactory.getRuntimeMXBean().getName();finalint index = jvmName.indexOf('@');if(index <1){// part before '@' empty (index = 0) / '@' not found (index = -1)return fallback;}try{returnLong.toString(Long.parseLong(jvmName.substring(0, index)));}catch(NumberFormatException e){// ignore}return fallback;}
O VisualVM usa código semelhante para obter PID próprio, verifique com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Eles são os especialistas, portanto parece uma solução confiável e multiplataforma.
Espinosa
O @Espinosa VisualVM suporta apenas a execução em uma JVM OpenJDK / Oracle / GraalVM (a partir de 2020). Isso significa que eles podem fazer suposições de acordo. Se você fizer o mesmo, você se tornará dependente do fornecedor e seu código poderá quebrar se estiver executando, por exemplo, J9.
Thorbjørn Ravn Andersen
24
Para JVM mais antiga, no linux ...
privatestaticString getPid()throwsIOException{byte[] bo =newbyte[256];InputStream is =newFileInputStream("/proc/self/stat");
is.read(bo);for(int i =0; i < bo.length; i++){if((bo[i]<'0')||(bo[i]>'9')){returnnewString(bo,0, i);}}return"-1";}
Se você vai fazer isso, basta fazer int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. Por que as girações extras?
precisa
2
Para os curiosos, o truque no comentário de @David realmente funciona. Alguém pode dizer o porquê? Algum tipo de mágica no getCanonicalFile()método que converte "self" no PID?
GreenGiant 2/12/12
7
O getCanonicalFile () resolve o link simbólico / proc / self / -> / proc / 1234, tente ls -al / proc / self #
Michael Michael
2
@DavidCitron +1! você está certo, eu não pensei em getCanonicalFile :-)
ggrandes
18
Você pode conferir o meu projeto: JavaSysMon no GitHub. Ele fornece a identificação do processo e várias outras coisas (uso da CPU, uso da memória) entre plataformas (atualmente Windows, Mac OSX, Linux e Solaris)
Você pode explicar como obter uma instância de processo para o processo atual em execução no Java 9?
Augusto
Ótima resposta para o uso do Java 9 em 2016! Você pode adicionar um link para os javadocs? graças
crazyGuy
8
Em Scala:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
Isso deve fornecer uma solução alternativa nos sistemas Unix até que o Java 9 seja lançado. (Eu sei, a pergunta era sobre Java, mas como não há uma pergunta equivalente para o Scala, eu gostaria de deixar isso para os usuários do Scala que possam encontrar a mesma pergunta.)
O mais recente que descobri é que existe uma propriedade do sistema chamada sun.java.launcher.pidque está disponível pelo menos no linux. Meu plano é usar isso e, se não for encontrado, use o JMX bean.
No meu caso com o Ubuntu 16.04 e Java 8, ele retorna nulo
david.perez
4
Depende de onde você está procurando as informações.
Se você estiver procurando as informações do console, poderá usar o comando jps. O comando fornece uma saída semelhante ao comando ps do Unix e vem com o JDK, pois acredito que o 1.5
Se você está procurando pelo processo, o RuntimeMXBean (como dito por Wouter Coekaerts) é provavelmente a sua melhor escolha. A saída de getName () no Windows usando o Sun JDK 1.6 u7 está no formato [PROCESS_ID] @ [MACHINE_NAME]. No entanto, você pode tentar executar jps e analisar o resultado disso:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
Se executado sem opções, a saída deve ser a identificação do processo seguida pelo nome.
A ferramenta JPS usa a biblioteca jvmstat, parte do tools.jar. Veja meu exemplo ou consulte o código-fonte JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . Não há necessidade de chamar o JPS como processo externo, use a biblioteca jvmstat diretamente.
Espinosa
4
Esse é o código que JConsole usa e potencialmente o jps e o VisualVM. Ele utiliza classes do
sun.jvmstat.monitor.*pacote, de tool.jar.
o tool.jar é uma biblioteca distribuída com o Oracle JDK, mas não o JRE!
Você não pode obter tool.jar do repositório Maven; configurá-lo com o Maven é um pouco complicado
o tool.jar provavelmente contém código dependente de plataforma (nativo?) Por isso não é facilmente distribuível
Ele é executado sob a premissa de que todos os aplicativos JVM em execução (locais) são "monitoráveis". Parece que no Java 6 todos os aplicativos geralmente são (a menos que você configure ativamente o oposto)
Provavelmente funciona apenas para Java 6+
O Eclipse não publica a classe principal, portanto você não obterá facilmente o Eclipse PID Bug no MonitoredVmUtil?
ATUALIZAÇÃO: Acabei de verificar se o JPS usa dessa maneira, ou seja, a biblioteca Jvmstat (parte do tool.jar). Portanto, não há necessidade de chamar o JPS como processo externo, chame a biblioteca Jvmstat diretamente, como mostra meu exemplo. Você também pode obter uma lista de todas as JVMs em execução no host local dessa maneira. Veja o código fonte JPS :
Eu sei que esse é um encadeamento antigo, mas eu queria chamar a atenção de que a API para obter o PID (assim como outras manipulações do processo Java no tempo de execução) está sendo adicionada à classe Process no JDK 9: http: // openjdk. java.net/jeps/102
Este não verifica se o PID está em uso, mas se pid é igual pid processo atual
c0der
Qual é a solução correta para atualizar meu código?
PartialData
-6
Isso é o que eu usei quando tinha requisitos semelhantes. Isso determina o PID do processo Java corretamente. Deixe seu código java gerar um servidor em um número de porta predefinido e execute comandos do SO para descobrir o PID que está ouvindo na porta. Para Linux
Respostas:
Não existe uma maneira independente de plataforma que possa garantir que funcione em todas as implementações da jvm.
ManagementFactory.getRuntimeMXBean().getName()
parece a melhor solução (mais próxima). É curto e provavelmente funciona em todas as implementações de uso amplo.No linux + windows, ele retorna um valor como
12345@hostname
(12345
sendo o ID do processo). Cuidado, porém, de acordo com os documentos , não há garantias sobre esse valor:No Java 9, a nova API de processo pode ser usada:
fonte
Você poderia usar o JNA . Infelizmente, ainda não existe uma API JNA comum para obter o ID do processo atual, mas cada plataforma é bastante simples:
janelas
Certifique-se de ter
jna-platform.jar
:Unix
Declarar:
Então:
Java 9
No Java 9, a nova API do processo pode ser usada para obter o ID do processo atual. Primeiro, você pega um identificador para o processo atual e, em seguida, consulta o PID:
fonte
getpid()
solução também funciona para o OS X, com uma chamada JNA para a biblioteca "System".error: cannot find symbol
para jdk9Aqui está um método backdoor que pode não funcionar com todas as VMs, mas deve funcionar no Linux e no Windows ( exemplo original aqui ):
fonte
getDeclaredMethod
no objeto retornado porjvm.get(runtime)
.Tente Sigar . APIs muito extensas. Licença Apache 2.
fonte
O método a seguir tenta extrair o PID de
java.lang.management.ManagementFactory
:Basta ligar
getProcessId("<PID>")
, por exemplo.fonte
Para JVM mais antiga, no linux ...
fonte
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. Por que as girações extras?getCanonicalFile()
método que converte "self" no PID?Você pode conferir o meu projeto: JavaSysMon no GitHub. Ele fornece a identificação do processo e várias outras coisas (uso da CPU, uso da memória) entre plataformas (atualmente Windows, Mac OSX, Linux e Solaris)
fonte
Desde o Java 9, existe um método Process.getPid () que retorna o ID nativo de um processo:
Para obter o ID do processo Java atual, pode-se usar a
ProcessHandle
interface:fonte
Em Scala:
Isso deve fornecer uma solução alternativa nos sistemas Unix até que o Java 9 seja lançado. (Eu sei, a pergunta era sobre Java, mas como não há uma pergunta equivalente para o Scala, eu gostaria de deixar isso para os usuários do Scala que possam encontrar a mesma pergunta.)
fonte
Para completar, existe um wrapper no Spring Boot para o
solução. Se um número inteiro for necessário, isso pode ser resumido na linha única:
Se alguém já usa a inicialização Spring, ele pode usar org.springframework.boot.ApplicationPid
O método toString () imprime o pid ou '???'.
Advertências sobre o ManagementFactory já são discutidas em outras respostas.
fonte
fonte
fonte
O mais recente que descobri é que existe uma propriedade do sistema chamada
sun.java.launcher.pid
que está disponível pelo menos no linux. Meu plano é usar isso e, se não for encontrado, use oJMX bean
.fonte
Depende de onde você está procurando as informações.
Se você estiver procurando as informações do console, poderá usar o comando jps. O comando fornece uma saída semelhante ao comando ps do Unix e vem com o JDK, pois acredito que o 1.5
Se você está procurando pelo processo, o RuntimeMXBean (como dito por Wouter Coekaerts) é provavelmente a sua melhor escolha. A saída de getName () no Windows usando o Sun JDK 1.6 u7 está no formato [PROCESS_ID] @ [MACHINE_NAME]. No entanto, você pode tentar executar jps e analisar o resultado disso:
Se executado sem opções, a saída deve ser a identificação do processo seguida pelo nome.
fonte
Esse é o código que JConsole usa e potencialmente o jps e o VisualVM. Ele utiliza classes do
sun.jvmstat.monitor.*
pacote, detool.jar
.Existem poucas capturas:
tool.jar
é uma biblioteca distribuída com o Oracle JDK, mas não o JRE!tool.jar
do repositório Maven; configurá-lo com o Maven é um pouco complicadotool.jar
provavelmente contém código dependente de plataforma (nativo?) Por isso não é facilmente distribuívelATUALIZAÇÃO: Acabei de verificar se o JPS usa dessa maneira, ou seja, a biblioteca Jvmstat (parte do tool.jar). Portanto, não há necessidade de chamar o JPS como processo externo, chame a biblioteca Jvmstat diretamente, como mostra meu exemplo. Você também pode obter uma lista de todas as JVMs em execução no host local dessa maneira. Veja o código fonte JPS :
fonte
Estou adicionando isso a outras soluções.
com Java 10, para obter
process id
fonte
Com base na resposta de Ashwin Jayaprakash (+1) sobre o Apache 2.0 licenciado
SIGAR
, eis como eu o uso para obter apenas o PID do processo atual:Mesmo que não funcione em todas as plataformas, funciona no Linux, Windows, OS X e várias plataformas Unix, conforme listado aqui .
fonte
Você pode tentar
getpid()
no JNR-Posix .Ele possui um wrapper do Windows POSIX que chama getpid () da libc.
fonte
Eu sei que esse é um encadeamento antigo, mas eu queria chamar a atenção de que a API para obter o PID (assim como outras manipulações do processo Java no tempo de execução) está sendo adicionada à classe Process no JDK 9: http: // openjdk. java.net/jeps/102
fonte
Encontrei uma solução que pode ser um pouco complicada e não tentei em outro sistema operacional que não o Windows 10, mas acho que vale a pena notar.
Se você estiver trabalhando com J2V8 e nodejs, poderá executar uma função javascript simples retornando o pid do processo java.
Aqui está um exemplo:
fonte
Aqui está a minha solução:
fonte
Isso é o que eu usei quando tinha requisitos semelhantes. Isso determina o PID do processo Java corretamente. Deixe seu código java gerar um servidor em um número de porta predefinido e execute comandos do SO para descobrir o PID que está ouvindo na porta. Para Linux
fonte
bash -c 'echo $PPID'
ou o / proc respostas acima