No existe una forma independiente de la plataforma que pueda garantizarse que funcione en todas las implementaciones de jvm.
ManagementFactory.getRuntimeMXBean().getName()Parece la mejor solución (más cercana). Es breve, y probablemente funciona en todas las implementaciones en uso amplio.
En linux + windows devuelve un valor como 12345@hostname( 12345siendo el id del proceso). Sin embargo, tenga en cuenta que según los documentos , no hay garantías sobre este valor:
Devuelve el nombre que representa la máquina virtual Java en ejecución. La cadena de nombre devuelta puede ser cualquier cadena arbitraria y una implementación de máquina virtual Java puede elegir incrustar información útil específica de la plataforma en la cadena de nombre devuelta. Cada máquina virtual en ejecución podría tener un nombre diferente.
En Java 9, la nueva API de proceso se puede utilizar para obtener la ID del proceso actual. Primero, toma un identificador del proceso actual, luego consulta el PID:
+1 Pero me temo que en un entorno con restricciones de seguridad no debería funcionar (tomcat, WebLogic, etc.).
ATorras
La getpid()solución también funciona para OS X, con una llamada JNA a la biblioteca "Sistema".
Daniel Widdis
Sin embargo, me sale error: cannot find symbolpara jdk9
skytree
56
Aquí hay un método de puerta trasera que podría no funcionar con todas las máquinas virtuales, pero debería funcionar tanto en Linux como en Windows ( ejemplo original aquí ):
muy bueno, solo verifiqué que funciona tanto en JRockit como en JVM de Hotspot.
Drupad Panchal
1
Buena solución. Asumiré que hay una buena razón por la cual este método (y otros en la clase) no son públicos y de fácil acceso, y tengo curiosidad por saber de qué se trata.
fragorl
2
El equipo de Oracle Java ha anunciado que tienen la intención de ocultar todos los paquetes que no sean Java (es decir, sun. *). Creo que comenzará con Java 10 (programado para 2018, tal vez Java 9). Si tiene una implementación similar a la anterior, es posible que desee encontrar una alternativa para que su código no se rompa.
hfontanez
Tampoco funciona para mí, ya que los paquetes sun. * Probablemente se eliminan o son inaccesibles (VMManagement no se puede resolver a un tipo).
Mike Stoddart el
Debido a la forma en que funciona la reflexión, no se necesita acceso a sun.management. *. Simplemente realice el getDeclaredMethoden el Objeto devuelto por jvm.get(runtime).
Andrew T Finnell
36
Prueba con Sigar . API muy extensas. Apache 2 licencia.
Tendría muchos más votos a favor si explicara cómo usar SIGAR para esto
Brad Mace
1
El enlace está roto. Da un ejemplo de cómo usar esto, pero ¿hay alguna dependencia de Maven para ello?
Jules
github.com/hyperic/sigar parece ser una ubicación utilizable; Esto también muestra que es un código nativo con enlaces Java, lo que puede hacer que sea menos una solución para muchos contextos.
Zastai
26
El siguiente método intenta extraer el 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;}
VisualVM usa un código similar para obtener el PID propio, verifique com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Ellos son los expertos, por lo que parece una solución confiable y multiplataforma.
Espinosa
@Espinosa VisualVM solo admite la ejecución en OpenJDK / Oracle / GraalVM JVM (a partir de 2020). Esto significa que pueden hacer suposiciones en consecuencia. Si hace lo mismo, dependerá del proveedor y su código puede romperse si se ejecuta, por ejemplo, en J9.
Thorbjørn Ravn Andersen
24
Para JVM anteriores, en 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";}
Si vas a hacer eso, entonces solo hazlo int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. ¿Por qué los giros extra?
David Citron
2
Para los curiosos, el truco en el comentario de @David realmente funciona. ¿Alguien puede decir por qué? ¿Algún tipo de magia en el getCanonicalFile()método que convierte "self" al PID?
@DavidCitron +1! tienes razón, no pensé en getCanonicalFile :-)
ggrandes
18
Puedes ver mi proyecto: JavaSysMon en GitHub. Proporciona id de proceso y un montón de otras cosas (uso de CPU, uso de memoria) multiplataforma (actualmente Windows, Mac OSX, Linux y Solaris)
¿Puede explicar cómo obtener una instancia de Proceso para el proceso actual en ejecución en Java 9?
Augusto
¡Gran respuesta para usar Java 9 en 2016! ¿Puedes agregar un enlace a los javadocs? gracias
crazyGuy
8
En Scala:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
Esto debería darle una solución alternativa en los sistemas Unix hasta que se lance Java 9. (Lo sé, la pregunta era sobre Java, pero como no hay una pregunta equivalente para Scala, quería dejar esto para los usuarios de Scala que podrían tropezar con la misma pregunta).
Lo último que he encontrado es que hay una propiedad del sistema llamada sun.java.launcher.pidque está disponible al menos en Linux. Mi plan es usar eso y, si no se encuentra, usar el JMX bean.
En mi caso con Ubuntu 16.04 y Java 8, devuelve nulo
david.perez
4
Depende de dónde esté buscando la información.
Si está buscando la información de la consola, puede usar el comando jps. El comando da una salida similar al comando Unix ps y viene con el JDK ya que creo que 1.5
Si está buscando en el proceso, RuntimeMXBean (como dijo Wouter Coekaerts) es probablemente su mejor opción. El resultado de getName () en Windows con Sun JDK 1.6 u7 tiene el formato [PROCESS_ID] @ [MACHINE_NAME]. Sin embargo, podría intentar ejecutar jps y analizar el resultado a partir de eso:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
Si se ejecuta sin opciones, la salida debería ser la identificación del proceso seguida del nombre.
La herramienta JPS utiliza la biblioteca jvmstat, parte de tools.jar. Consulte mi ejemplo o vea el código fuente JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . No es necesario llamar a JPS como proceso externo, use la biblioteca jvmstat directamente.
Espinosa
4
Este es el código JConsole, y potencialmente utiliza jps y VisualVM. Utiliza clases de
sun.jvmstat.monitor.*paquete, de tool.jar.
los tool.jar Es una biblioteca distribuida con Oracle JDK pero no con JRE!
No puedes conseguir tool.jar del repositorio de Maven; configurarlo con Maven es un poco complicado
los tool.jar probablemente contiene código dependiente de la plataforma (nativo?) Por lo que no es fácilmente distribuibles
Se ejecuta bajo el supuesto de que todas las aplicaciones JVM (locales) que se ejecutan son "monitoreables". Parece que desde Java 6 todas las aplicaciones generalmente lo son (a menos que configure activamente lo contrario)
Probablemente solo funcione para Java 6+
Eclipse no publica la clase principal, por lo que no obtendrá Eclipse PID fácilmente ¿Error en MonitoredVmUtil?
ACTUALIZACIÓN: Acabo de comprobar que JPS usa de esta manera, es decir, la biblioteca Jvmstat (parte de tool.jar). Por lo tanto, no es necesario llamar a JPS como proceso externo, llame a la biblioteca Jvmstat directamente como lo muestra mi ejemplo. También puede obtener la lista de todas las JVM que se ejecutan en localhost de esta manera. Ver código fuente JPS :
Sé que este es un hilo antiguo, pero quería llamar a esa API para obtener el PID (así como otra manipulación del proceso Java en tiempo de ejecución) que se agrega a la clase Process en JDK 9: http: // openjdk. java.net/jeps/102
Wow, eso fue rápido. ¡Solo tomó unos siete años! 😃
Dmitry Shechtman
1
Encontré una solución que puede ser un poco marginal y no la probé en otro sistema operativo que no sea Windows 10, pero creo que vale la pena notarlo.
Si se encuentra trabajando con J2V8 y nodejs, puede ejecutar una función javascript simple que le devolverá el pid del proceso java.
Esto no verifica si pid está en uso, pero si pid es igual al proceso actual pid
c0der
¿Cuál es la solución correcta para poder actualizar mi código?
PartialData
-6
Esto es lo que usé cuando tenía un requisito similar. Esto determina el PID del proceso Java correctamente. Deje que su código Java genere un servidor en un número de puerto predefinido y luego ejecute comandos del sistema operativo para descubrir el PID que escucha en el puerto. Para Linux
Respuestas:
No existe una forma independiente de la plataforma que pueda garantizarse que funcione en todas las implementaciones de jvm.
ManagementFactory.getRuntimeMXBean().getName()
Parece la mejor solución (más cercana). Es breve, y probablemente funciona en todas las implementaciones en uso amplio.En linux + windows devuelve un valor como
12345@hostname
(12345
siendo el id del proceso). Sin embargo, tenga en cuenta que según los documentos , no hay garantías sobre este valor:En Java 9 , se puede utilizar la nueva API de proceso :
fuente
Podrías usar JNA . Desafortunadamente, todavía no hay una API JNA común para obtener la ID de proceso actual, pero cada plataforma es bastante simple:
Ventanas
Asegúrate de tener
jna-platform.jar
entonces:Unix
Declarar:
Entonces:
Java 9
En Java 9, la nueva API de proceso se puede utilizar para obtener la ID del proceso actual. Primero, toma un identificador del proceso actual, luego consulta el PID:
fuente
getpid()
solución también funciona para OS X, con una llamada JNA a la biblioteca "Sistema".error: cannot find symbol
para jdk9Aquí hay un método de puerta trasera que podría no funcionar con todas las máquinas virtuales, pero debería funcionar tanto en Linux como en Windows ( ejemplo original aquí ):
fuente
getDeclaredMethod
en el Objeto devuelto porjvm.get(runtime)
.Prueba con Sigar . API muy extensas. Apache 2 licencia.
fuente
El siguiente método intenta extraer el PID de
java.lang.management.ManagementFactory
:Solo llame
getProcessId("<PID>")
, por ejemplo.fuente
Para JVM anteriores, en Linux ...
fuente
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. ¿Por qué los giros extra?getCanonicalFile()
método que convierte "self" al PID?Puedes ver mi proyecto: JavaSysMon en GitHub. Proporciona id de proceso y un montón de otras cosas (uso de CPU, uso de memoria) multiplataforma (actualmente Windows, Mac OSX, Linux y Solaris)
fuente
Desde Java 9 hay un método Process.getPid () que devuelve la ID nativa de un proceso:
Para obtener la ID del proceso del proceso Java actual, se puede usar la
ProcessHandle
interfaz:fuente
En Scala:
Esto debería darle una solución alternativa en los sistemas Unix hasta que se lance Java 9. (Lo sé, la pregunta era sobre Java, pero como no hay una pregunta equivalente para Scala, quería dejar esto para los usuarios de Scala que podrían tropezar con la misma pregunta).
fuente
Para completar, hay un contenedor en Spring Boot para
solución. Si se requiere un número entero, esto se puede resumir en una línea:
Si alguien ya usa Spring boot, él / ella puede usar org.springframework.boot.ApplicationPid
El método toString () imprime el pid o '???'.
Las advertencias que usan ManagementFactory ya se analizan en otras respuestas.
fuente
fuente
fuente
Lo último que he encontrado es que hay una propiedad del sistema llamada
sun.java.launcher.pid
que está disponible al menos en Linux. Mi plan es usar eso y, si no se encuentra, usar elJMX bean
.fuente
Depende de dónde esté buscando la información.
Si está buscando la información de la consola, puede usar el comando jps. El comando da una salida similar al comando Unix ps y viene con el JDK ya que creo que 1.5
Si está buscando en el proceso, RuntimeMXBean (como dijo Wouter Coekaerts) es probablemente su mejor opción. El resultado de getName () en Windows con Sun JDK 1.6 u7 tiene el formato [PROCESS_ID] @ [MACHINE_NAME]. Sin embargo, podría intentar ejecutar jps y analizar el resultado a partir de eso:
Si se ejecuta sin opciones, la salida debería ser la identificación del proceso seguida del nombre.
fuente
Este es el código JConsole, y potencialmente utiliza jps y VisualVM. Utiliza clases de
sun.jvmstat.monitor.*
paquete, detool.jar
.Hay pocas capturas:
tool.jar
Es una biblioteca distribuida con Oracle JDK pero no con JRE!tool.jar
del repositorio de Maven; configurarlo con Maven es un poco complicadotool.jar
probablemente contiene código dependiente de la plataforma (nativo?) Por lo que no es fácilmente distribuiblesACTUALIZACIÓN: Acabo de comprobar que JPS usa de esta manera, es decir, la biblioteca Jvmstat (parte de tool.jar). Por lo tanto, no es necesario llamar a JPS como proceso externo, llame a la biblioteca Jvmstat directamente como lo muestra mi ejemplo. También puede obtener la lista de todas las JVM que se ejecutan en localhost de esta manera. Ver código fuente JPS :
fuente
Estoy agregando esto, a otras soluciones.
con Java 10, para obtener
process id
fuente
Basado en la respuesta de Ashwin Jayaprakash (+1) sobre la licencia Apache 2.0
SIGAR
, así es como lo uso para obtener solo el PID del proceso actual:Aunque no funciona en todas las plataformas, funciona en Linux, Windows, OS X y varias plataformas Unix como se enumeran aquí .
fuente
Puedes probar
getpid()
en JNR-Posix .Tiene un contenedor POSIX de Windows que invoca getpid () fuera de libc.
fuente
Sé que este es un hilo antiguo, pero quería llamar a esa API para obtener el PID (así como otra manipulación del proceso Java en tiempo de ejecución) que se agrega a la clase Process en JDK 9: http: // openjdk. java.net/jeps/102
fuente
Encontré una solución que puede ser un poco marginal y no la probé en otro sistema operativo que no sea Windows 10, pero creo que vale la pena notarlo.
Si se encuentra trabajando con J2V8 y nodejs, puede ejecutar una función javascript simple que le devolverá el pid del proceso java.
Aquí hay un ejemplo:
fuente
Aquí está mi solución:
fuente
Esto es lo que usé cuando tenía un requisito similar. Esto determina el PID del proceso Java correctamente. Deje que su código Java genere un servidor en un número de puerto predefinido y luego ejecute comandos del sistema operativo para descubrir el PID que escucha en el puerto. Para Linux
fuente
bash -c 'echo $PPID'
o las respuestas