Nie istnieje sposób niezależny od platformy, który gwarantowałby działanie we wszystkich implementacjach Jvm.
ManagementFactory.getRuntimeMXBean().getName()wygląda jak najlepsze (najbliższe) rozwiązanie. Jest krótki i prawdopodobnie działa w każdej implementacji w szerokim użyciu.
W systemie Linux + Windows zwraca wartość typu 12345@hostname( 12345będącą identyfikatorem procesu). Uważaj jednak, że zgodnie z dokumentami nie ma żadnych gwarancji dotyczących tej wartości:
Zwraca nazwę reprezentującą działającą maszynę wirtualną Java. Zwrócony ciąg nazwy może być dowolnym dowolnym ciągiem, a implementacja wirtualnej maszyny Java może osadzić przydatne informacje specyficzne dla platformy w zwróconym ciągu nazwy. Każda działająca maszyna wirtualna może mieć inną nazwę.
Możesz użyć JNA . Niestety nie ma jeszcze wspólnego interfejsu API JNA, aby uzyskać bieżący identyfikator procesu, ale każda platforma jest dość prosta:
W Javie 9 nowy interfejs API procesu może być używany do uzyskania bieżącego identyfikatora procesu. Najpierw łapiesz uchwyt do bieżącego procesu, a następnie odpytujesz PID:
+1 Ale obawiam się, że w środowisku o ograniczonym bezpieczeństwie nie powinno działać (tomcat, WebLogic itp.).
ATorras,
getpid()Rozwiązanie działa również dla OS X, z uprzednim JNA do biblioteki „System”.
Daniel Widdis
Jednak mam error: cannot find symboldla jdk9
skytree
56
Oto metoda backdoora, która może nie działać ze wszystkimi maszynami wirtualnymi, ale powinna działać zarówno na systemie Linux, jak i Windows ( oryginalny przykład tutaj ):
bardzo fajnie, właśnie zweryfikowałem, że działa zarówno na JRockit, jak i na Hotspot JVM.
Drupad Panchal,
1
Niezłe obejście. Zakładam, że istnieje dobry powód, dla którego ta metoda (i inne w klasie) nie jest publiczna i łatwo dostępna, i jestem ciekawy, co to jest.
fragorl
2
Zespół Oracle Java ogłosił, że zamierza ukryć wszystkie pakiety inne niż Java (tj. Sun. *). Wierzę, że począwszy od Java 10 (zaplanowanego na 2018 rok - może Java 9). Jeśli masz podobną implementację jak powyższa, możesz wymyślić alternatywę, aby Twój kod się nie zepsuł.
hfontanez
Nie działa dla mnie ani jako słońce. * Pakiety są prawdopodobnie usunięte lub niedostępne (VMManagement nie może być rozpoznany jako typ).
Mike Stoddart,
Ze względu na sposób działania odbicia dostęp do sun.management. * Nie jest potrzebny. Po prostu wykonaj getDeclaredMethodobiekt zwrócony przez jvm.get(runtime).
Andrew T Finnell,
36
Wypróbuj Sigar . bardzo rozbudowane interfejsy API. Licencja Apache 2.
Miałbyś o wiele więcej pozytywnych opinii, gdybyś wyjaśnił, jak do tego użyć SIGAR
Brad Mace
1
Link jest zepsuty. Dajesz przykład, jak z tego korzystać, ale czy jest w tym zależność od raju?
Jules
github.com/hyperic/sigar wydaje się być użyteczną lokalizacją; pokazuje to również, że jest to natywny kod z powiązaniami Java, co może sprawić, że będzie mniej rozwiązaniem dla wielu kontekstów.
Zastai
26
Poniższa metoda próbuje wyodrębnić PID z 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 używa podobnego kodu do uzyskania własnego PID, sprawdź com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Są ekspertami, więc wygląda na niezawodne, wieloplatformowe rozwiązanie.
Espinosa,
@Espinosa VisualVM obsługuje tylko uruchomioną JVM OpenJDK / Oracle / GraalVM (od 2020 r.). Oznacza to, że mogą odpowiednio przyjmować założenia. Jeśli zrobisz to samo, uzależnisz się od dostawcy i kod może się zepsuć, jeśli uruchomisz na przykład J9.
Thorbjørn Ravn Andersen
24
Dla starszych JVM, w systemie 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";}
Jeśli masz zamiar to zrobić, po prostu zrób int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. Dlaczego dodatkowe wahania?
David Citron,
2
Dla ciekawskich sztuczka w komentarzu @Davida faktycznie działa. Czy ktoś może powiedzieć dlaczego? Jakaś magia w getCanonicalFile()metodzie, która przekształca „jaźń” w PID?
@DavidCitron +1! masz rację, nie myślałem w getCanonicalFile :-)
grgrandes
18
Możesz sprawdzić mój projekt: JavaSysMon na GitHub. Zapewnia identyfikator procesu i kilka innych rzeczy (użycie procesora, użycie pamięci) na różnych platformach (obecnie Windows, Mac OSX, Linux i Solaris)
Czy możesz wyjaśnić, jak uzyskać instancję procesu dla bieżącego procesu w Javie 9?
Augusto,
Świetna odpowiedź na używanie Java 9 w 2016 roku! Czy możesz dodać link do javadocs? dzięki
crazyGuy
8
W Scali:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
To powinno dać ci obejście na systemach Unix do czasu wydania Java 9. (Wiem, że pytanie dotyczyło Javy, ale ponieważ nie ma równoważnego pytania dla Scali, chciałem zostawić to użytkownikom Scali, którzy mogą natknąć się na to samo pytanie).
Ostatnie stwierdziłem, że istnieje właściwość systemowa o nazwie, sun.java.launcher.pidktóra jest dostępna przynajmniej w systemie Linux. Mój plan jest taki, a jeśli nie można go użyć JMX bean.
W moim przypadku z Ubuntu 16.04 i Javą 8 zwraca wartość null
david.perez
4
To zależy od tego, skąd szukasz informacji.
Jeśli szukasz informacji z konsoli, możesz użyć polecenia jps. Polecenie daje dane wyjściowe podobne do polecenia ps w systemie Unix i jest dostarczane z JDK, ponieważ uważam, że 1.5
Jeśli szukasz z procesu, RuntimeMXBean (jak powiedział Wouter Coekaerts) jest prawdopodobnie najlepszym wyborem. Dane wyjściowe getName () w systemie Windows używającym Sun JDK 1.6 u7 mają postać [PROCESS_ID] @ [MACHINE_NAME]. Możesz jednak spróbować wykonać jps i przeanalizować wynik:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
Jeśli uruchamiany jest bez opcji, wynikiem powinien być identyfikator procesu, a po nim nazwa.
Narzędzie JPS wykorzystuje bibliotekę jvmstat, część narzędzia.jar. Sprawdź mój przykład lub zobacz kod źródłowy JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . Nie ma potrzeby wywoływania JPS jako procesu zewnętrznego, użyj biblioteki jvmstat bezpośrednio.
Espinosa,
4
Jest to kod JConsole i potencjalnie używa jps i VisualVM. Wykorzystuje klasy z
sun.jvmstat.monitor.*pakietu, z tool.jar.
The tool.jarJest biblioteką rozprowadzany z Oracle JDK ale nie JRE!
Nie możesz dostać tool.jar z repozytorium Maven; skonfigurowanie go za pomocą Maven jest nieco trudne
The tool.jarPrawdopodobnie zawiera platform zależnej (native?) Kodu, więc nie jest łatwo dystrybuowana
Działa przy założeniu, że wszystkie (lokalne) działające aplikacje JVM są „monitorowalne”. Wygląda na to, że z Javy 6 ogólnie wszystkie aplikacje są (chyba że aktywnie skonfigurujesz odwrotnie)
Prawdopodobnie działa tylko dla Java 6+
Eclipse nie publikuje głównej klasy, więc nie dostaniesz łatwo Eclipse PID Błąd w MonitoredVmUtil?
AKTUALIZACJA: Właśnie dwukrotnie sprawdziłem, czy JPS używa tej metody, to znaczy biblioteki Jvmstat (część tool.jar). Nie ma więc potrzeby wywoływania JPS jako zewnętrznego procesu, wywoływania biblioteki Jvmstat bezpośrednio, jak pokazuje mój przykład. W ten sposób można również uzyskać listę wszystkich JVM uruchomionych na localhost. Zobacz kod źródłowy JPS :
Wiem, że to stary wątek, ale chciałem przywołać ten interfejs API do pobierania PID (a także innych manipulacji procesem Java w czasie wykonywania) jest dodawany do klasy Process w JDK 9: http: // openjdk. java.net/jeps/102
Wow, to było szybkie. Zajęło to tylko około siedmiu lat! 😃
Dmitry
1
Znalazłem rozwiązanie, które może być trochę przypadkowe i nie wypróbowałem go na innym systemie operacyjnym niż Windows 10, ale myślę, że warto to zauważyć.
Jeśli znajdziesz pracę z J2V8 i nodejs, możesz uruchomić prostą funkcję javascript zwracającą ci pid procesu java.
Nie sprawdza to, czy pid jest w użyciu, ale czy pid jest równy bieżącemu procesowi pid
c0der
Jakie jest prawidłowe rozwiązanie, aby zaktualizować kod?
PartialData
-6
Tego właśnie użyłem, gdy miałem podobne wymagania. To poprawnie określa PID procesu Java. Pozwól, aby kod Java odrodził serwer na wstępnie zdefiniowanym numerze portu, a następnie uruchom komendę systemu operacyjnego, aby dowiedzieć się, czy PID nasłuchuje na porcie. Dla systemu Linux
Odpowiedzi:
Nie istnieje sposób niezależny od platformy, który gwarantowałby działanie we wszystkich implementacjach Jvm.
ManagementFactory.getRuntimeMXBean().getName()
wygląda jak najlepsze (najbliższe) rozwiązanie. Jest krótki i prawdopodobnie działa w każdej implementacji w szerokim użyciu.W systemie Linux + Windows zwraca wartość typu
12345@hostname
(12345
będącą identyfikatorem procesu). Uważaj jednak, że zgodnie z dokumentami nie ma żadnych gwarancji dotyczących tej wartości:W Javie 9 można użyć nowego interfejsu API procesu :
źródło
Możesz użyć JNA . Niestety nie ma jeszcze wspólnego interfejsu API JNA, aby uzyskać bieżący identyfikator procesu, ale każda platforma jest dość prosta:
Windows
Upewnij się, że masz
jna-platform.jar
:Unix
Ogłosić:
Następnie:
Java 9
W Javie 9 nowy interfejs API procesu może być używany do uzyskania bieżącego identyfikatora procesu. Najpierw łapiesz uchwyt do bieżącego procesu, a następnie odpytujesz PID:
źródło
getpid()
Rozwiązanie działa również dla OS X, z uprzednim JNA do biblioteki „System”.error: cannot find symbol
dla jdk9Oto metoda backdoora, która może nie działać ze wszystkimi maszynami wirtualnymi, ale powinna działać zarówno na systemie Linux, jak i Windows ( oryginalny przykład tutaj ):
źródło
getDeclaredMethod
obiekt zwrócony przezjvm.get(runtime)
.Wypróbuj Sigar . bardzo rozbudowane interfejsy API. Licencja Apache 2.
źródło
Poniższa metoda próbuje wyodrębnić PID z
java.lang.management.ManagementFactory
:Na
getProcessId("<PID>")
przykład zadzwoń .źródło
Dla starszych JVM, w systemie Linux ...
źródło
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. Dlaczego dodatkowe wahania?getCanonicalFile()
metodzie, która przekształca „jaźń” w PID?Możesz sprawdzić mój projekt: JavaSysMon na GitHub. Zapewnia identyfikator procesu i kilka innych rzeczy (użycie procesora, użycie pamięci) na różnych platformach (obecnie Windows, Mac OSX, Linux i Solaris)
źródło
Od wersji Java 9 istnieje metoda Process.getPid (), która zwraca natywny identyfikator procesu:
Aby uzyskać identyfikator bieżącego procesu Java, można użyć
ProcessHandle
interfejsu:źródło
W Scali:
To powinno dać ci obejście na systemach Unix do czasu wydania Java 9. (Wiem, że pytanie dotyczyło Javy, ale ponieważ nie ma równoważnego pytania dla Scali, chciałem zostawić to użytkownikom Scali, którzy mogą natknąć się na to samo pytanie).
źródło
Dla kompletności jest opakowanie w Spring Boot dla
rozwiązanie. Jeśli wymagana jest liczba całkowita, można to zsumować do jednej linijki:
Jeśli ktoś już używa Spring Boot, może użyć org.springframework.boot.ApplicationPid
Metoda toString () wypisuje pid lub „???”.
Ostrzeżenia dotyczące korzystania z ManagementFactory zostały już omówione w innych odpowiedziach.
źródło
źródło
źródło
Ostatnie stwierdziłem, że istnieje właściwość systemowa o nazwie,
sun.java.launcher.pid
która jest dostępna przynajmniej w systemie Linux. Mój plan jest taki, a jeśli nie można go użyćJMX bean
.źródło
To zależy od tego, skąd szukasz informacji.
Jeśli szukasz informacji z konsoli, możesz użyć polecenia jps. Polecenie daje dane wyjściowe podobne do polecenia ps w systemie Unix i jest dostarczane z JDK, ponieważ uważam, że 1.5
Jeśli szukasz z procesu, RuntimeMXBean (jak powiedział Wouter Coekaerts) jest prawdopodobnie najlepszym wyborem. Dane wyjściowe getName () w systemie Windows używającym Sun JDK 1.6 u7 mają postać [PROCESS_ID] @ [MACHINE_NAME]. Możesz jednak spróbować wykonać jps i przeanalizować wynik:
Jeśli uruchamiany jest bez opcji, wynikiem powinien być identyfikator procesu, a po nim nazwa.
źródło
Jest to kod JConsole i potencjalnie używa jps i VisualVM. Wykorzystuje klasy z
sun.jvmstat.monitor.*
pakietu, ztool.jar
.Istnieje kilka połowów:
tool.jar
Jest biblioteką rozprowadzany z Oracle JDK ale nie JRE!tool.jar
z repozytorium Maven; skonfigurowanie go za pomocą Maven jest nieco trudnetool.jar
Prawdopodobnie zawiera platform zależnej (native?) Kodu, więc nie jest łatwo dystrybuowanaAKTUALIZACJA: Właśnie dwukrotnie sprawdziłem, czy JPS używa tej metody, to znaczy biblioteki Jvmstat (część tool.jar). Nie ma więc potrzeby wywoływania JPS jako zewnętrznego procesu, wywoływania biblioteki Jvmstat bezpośrednio, jak pokazuje mój przykład. W ten sposób można również uzyskać listę wszystkich JVM uruchomionych na localhost. Zobacz kod źródłowy JPS :
źródło
Dodam to do innych rozwiązań.
z Java 10, aby uzyskać
process id
źródło
Na podstawie ashwin Jayaprakash za odpowiedź (+1) o 2,0 licencją Apache
SIGAR
, tutaj jest, jak go używać, aby uzyskać tylko PID bieżącego procesu:Mimo że nie działa na wszystkich platformach, działa na systemach Linux, Windows, OS X i różnych platformach Unix wymienionych tutaj .
źródło
Możesz spróbować
getpid()
w JNR-Posix .Ma opakowanie systemu Windows POSIX, które wywołuje getpid () z libc.
źródło
Wiem, że to stary wątek, ale chciałem przywołać ten interfejs API do pobierania PID (a także innych manipulacji procesem Java w czasie wykonywania) jest dodawany do klasy Process w JDK 9: http: // openjdk. java.net/jeps/102
źródło
Znalazłem rozwiązanie, które może być trochę przypadkowe i nie wypróbowałem go na innym systemie operacyjnym niż Windows 10, ale myślę, że warto to zauważyć.
Jeśli znajdziesz pracę z J2V8 i nodejs, możesz uruchomić prostą funkcję javascript zwracającą ci pid procesu java.
Oto przykład:
źródło
Oto moje rozwiązanie:
źródło
Tego właśnie użyłem, gdy miałem podobne wymagania. To poprawnie określa PID procesu Java. Pozwól, aby kod Java odrodził serwer na wstępnie zdefiniowanym numerze portu, a następnie uruchom komendę systemu operacyjnego, aby dowiedzieć się, czy PID nasłuchuje na porcie. Dla systemu Linux
źródło
bash -c 'echo $PPID'
lub powyższe odpowiedzi