Не существует независимого от платформы способа, который гарантированно работал бы во всех реализациях jvm.
ManagementFactory.getRuntimeMXBean().getName()выглядит как лучшее (самое близкое) решение. Это коротко, и, вероятно, работает в каждой реализации в широком использовании.
В Linux + Windows он возвращает значение как 12345@hostname( 12345идентификатор процесса). Остерегайтесь, однако, в соответствии с документами , нет никаких гарантий относительно этого значения:
Возвращает имя, представляющее работающую виртуальную машину Java. Возвращенная строка имени может быть любой произвольной строкой, и реализация виртуальной машины Java может выбрать встраивание полезной информации для конкретной платформы в возвращенную строку имени. Каждая запущенная виртуальная машина может иметь свое имя.
В Java 9 может использоваться новый API процесса :
Вы могли бы использовать JNA . К сожалению, пока нет общего JNA API для получения текущего идентификатора процесса, но каждая платформа довольно проста:
В Java 9 новый API процесса может использоваться для получения текущего идентификатора процесса. Сначала вы берете дескриптор текущего процесса, затем запрашиваете PID:
+1 Но я боюсь, что в условиях безопасности это не должно работать (tomcat, WebLogic и т. Д.).
ATorras
getpid()Решение также работает на OS X, с помощью вызова ЮНА в библиотеку «System».
Даниэль Виддис
Тем не менее, я получаю error: cannot find symbolдля jdk9
Skytree
56
Вот метод backdoor, который может не работать со всеми виртуальными машинами, но должен работать как на Linux, так и на Windows ( оригинальный пример здесь ):
очень хорошо, только что проверил, что он работает как на JRockit, так и на JVM Hotspot.
Drupad Panchal
1
Хороший обходной путь. Я собираюсь предположить, что есть веская причина, почему этот метод (и другие в классе) не являются общедоступными и легкодоступными, и мне любопытно узнать, что это такое.
fragorl
2
Команда Oracle по Java объявила, что намерена скрыть все не-Java-пакеты (например, Sun. *). Я полагаю, начиная с Java 10 (запланировано на 2018 год - может быть, Java 9). Если у вас есть реализация, аналогичная приведенной выше, вы можете найти альтернативу, чтобы ваш код не сломался.
hfontanez
У меня не работает, так как пакеты sun. *, Вероятно, удалены или недоступны (VMManagement не может быть определен для типа).
Майк Стоддарт
Из-за того, как работает отражение, доступ к sun.management. * Не нужен. Просто выполните getDeclaredMethodобъект, возвращенный jvm.get(runtime).
Эндрю Т Финнелл
36
Попробуй Сигар . очень обширные API. Лицензия Apache 2.
У вас было бы намного больше голосов, если бы вы объяснили, как использовать SIGAR для этого
Брэд Мейс
1
Ссылка не работает. Вы привели пример того, как использовать это, но есть ли для него зависимость maven?
Жюль
github.com/hyperic/sigar - удобное для использования место; это также показывает, что это нативный код с привязками Java, что может сделать его менее подходящим для многих контекстов.
Застай
26
Следующий метод пытается извлечь PID из 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 использует подобный код для получения собственного PID, проверьте com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Они являются экспертами, поэтому это выглядит как надежное, кроссплатформенное решение.
Эспиноза
@Espinosa VisualVM поддерживает работу только на JVM OpenJDK / Oracle / GraalVM (по состоянию на 2020 год). Это означает, что они могут делать предположения соответственно. Если вы сделаете то же самое, вы станете зависимым от поставщика, и ваш код может сломаться, например, при работе на J9.
Торбьерн Равн Андерсен
24
Для старых JVM, в 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";}
Если вы собираетесь это сделать, тогда просто делайте int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. Почему лишние вращения?
Дэвид Цитрон
2
Любопытно, что трюк в комментарии @David действительно работает. Может кто-нибудь сказать почему? Какая-то магия в getCanonicalFile()методе, который преобразует «я» в PID?
@DavidCitron +1! Вы правы, я не думаю, что в getCanonicalFile :-)
ggrandes
18
Вы можете проверить мой проект: JavaSysMon на GitHub. Он предоставляет идентификатор процесса и кучу других вещей (использование процессора, использование памяти) кроссплатформенных (в настоящее время Windows, Mac OSX, Linux и Solaris)
Можете ли вы объяснить, как получить экземпляр Process для текущего запущенного процесса в Java 9?
Августо
Отличный ответ за использование Java 9 в 2016 году! Можете ли вы добавить ссылку на Javadocs? спасибо
crazyGuy
8
В Скала:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
Это должно дать вам обходной путь в системах Unix до выпуска Java 9. (Я знаю, что вопрос был о Java, но поскольку у Scala нет аналогичного вопроса, я хотел оставить это для пользователей Scala, которые могут наткнуться на тот же вопрос.)
Последнее я обнаружил, что есть свойство системы называется sun.java.launcher.pid, которая доступна по крайней мере , на Linux. Мой план состоит в том, чтобы использовать это, и если не найдено, чтобы использовать JMX bean.
В моем случае с Ubuntu 16.04 и Java 8 он возвращает null
david.perez
4
Это зависит от того, откуда вы ищете информацию.
Если вы ищете информацию из консоли, вы можете использовать команду jps. Команда выводит данные, аналогичные команде Unix ps, и поставляется с JDK, так как я считаю, что 1.5
Если вы смотрите на процесс, RuntimeMXBean (как сказал Wouter Coekaerts), вероятно, ваш лучший выбор. Вывод функции getName () в Windows с использованием Sun JDK 1.6 u7 имеет вид [PROCESS_ID] @ [MACHINE_NAME]. Однако вы можете попытаться выполнить jps и проанализировать результат из этого:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
Если запустить без параметров, вывод должен быть идентификатор процесса, а затем имя.
Инструмент JPS использует библиотеку jvmstat, часть tools.jar. Посмотрите мой пример или посмотрите исходный код JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . Нет необходимости вызывать JPS как внешний процесс, используйте библиотеку jvmstat напрямую.
Эспиноза
4
Это код JConsole, и, возможно, JPS и VisualVM использует. Он использует классы из
sun.jvmstat.monitor.*пакета, из tool.jar.
Это tool.jarбиблиотека, распространяемая вместе с Oracle JDK, но не JRE!
Вы не можете получить tool.jarот репозитория Maven; настроить его с Maven немного сложнее
tool.jar, Вероятно , содержит зависимый (родной?) Код платформы , так что не легко распространяемый
Он работает при условии, что все (локальные) запущенные приложения JVM являются «контролируемыми». Похоже, что из Java 6 все приложения, как правило, (если вы не настроили противоположное)
Вероятно, это работает только для Java 6+
Eclipse не публикует основной класс, поэтому вы не получите Eclipse PID легко Ошибка в MonitoredVmUtil?
ОБНОВЛЕНИЕ: я только что дважды проверил, что JPS использует этот способ, то есть библиотека Jvmstat (часть tool.jar). Так что нет необходимости вызывать JPS как внешний процесс, напрямую вызывать библиотеку Jvmstat, как показывает мой пример. Вы также можете получить список всех JVM, запущенных на localhost. Смотрите исходный код JPS :
Я знаю, что это старый поток, но я хотел сказать, что API для получения PID (а также другие манипуляции с процессом Java во время выполнения) добавляется в класс Process в JDK 9: http: // openjdk. java.net/jeps/102
Вау, это было быстро Это заняло всего около семи лет! Dmitry
Дмитрий Шехтман
1
Я нашел решение, которое может показаться немного странным, и я не пробовал его на других ОС, кроме Windows 10, но, думаю, стоит обратить на это внимание.
Если вы обнаружите, что работаете с J2V8 и nodejs, вы можете запустить простую функцию javascript, возвращающую вам pid процесса java.
Это не проверяет, используется ли pid, но если pid равен текущему pid процесса
c0der
Какое правильное решение, чтобы я мог обновить свой код?
PartialData
-6
Это то, что я использовал, когда у меня было подобное требование. Это правильно определяет PID процесса Java. Позвольте вашему Java-коду порождать сервер по заранее определенному номеру порта, а затем выполнять команды ОС, чтобы выяснить PID, прослушивающий порт. Для Linux
Ответы:
Не существует независимого от платформы способа, который гарантированно работал бы во всех реализациях jvm.
ManagementFactory.getRuntimeMXBean().getName()
выглядит как лучшее (самое близкое) решение. Это коротко, и, вероятно, работает в каждой реализации в широком использовании.В Linux + Windows он возвращает значение как
12345@hostname
(12345
идентификатор процесса). Остерегайтесь, однако, в соответствии с документами , нет никаких гарантий относительно этого значения:В Java 9 может использоваться новый API процесса :
источник
Вы могли бы использовать JNA . К сожалению, пока нет общего JNA API для получения текущего идентификатора процесса, но каждая платформа довольно проста:
Windows
Убедитесь, что у вас есть
jna-platform.jar
:Юникс
Объявляет:
Затем:
Java 9
В Java 9 новый API процесса может использоваться для получения текущего идентификатора процесса. Сначала вы берете дескриптор текущего процесса, затем запрашиваете PID:
источник
getpid()
Решение также работает на OS X, с помощью вызова ЮНА в библиотеку «System».error: cannot find symbol
для jdk9Вот метод backdoor, который может не работать со всеми виртуальными машинами, но должен работать как на Linux, так и на Windows ( оригинальный пример здесь ):
источник
getDeclaredMethod
объект, возвращенныйjvm.get(runtime)
.Попробуй Сигар . очень обширные API. Лицензия Apache 2.
источник
Следующий метод пытается извлечь PID из
java.lang.management.ManagementFactory
:Просто позвоните
getProcessId("<PID>")
, например.источник
Для старых JVM, в Linux ...
источник
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. Почему лишние вращения?getCanonicalFile()
методе, который преобразует «я» в PID?Вы можете проверить мой проект: JavaSysMon на GitHub. Он предоставляет идентификатор процесса и кучу других вещей (использование процессора, использование памяти) кроссплатформенных (в настоящее время Windows, Mac OSX, Linux и Solaris)
источник
Начиная с Java 9 существует метод Process.getPid (), который возвращает собственный идентификатор процесса:
Чтобы получить идентификатор текущего процесса Java, можно использовать
ProcessHandle
интерфейс:источник
В Скала:
Это должно дать вам обходной путь в системах Unix до выпуска Java 9. (Я знаю, что вопрос был о Java, но поскольку у Scala нет аналогичного вопроса, я хотел оставить это для пользователей Scala, которые могут наткнуться на тот же вопрос.)
источник
Для полноты в Spring Boot есть обертка для
решение. Если требуется целое число, то оно может быть суммировано до однострочного:
Если кто-то уже использует загрузку Spring, он / она может использовать org.springframework.boot.ApplicationPid
Метод toString () печатает pid или «???».
Предостережения, использующие ManagementFactory, уже обсуждались в других ответах.
источник
источник
источник
Последнее я обнаружил, что есть свойство системы называется
sun.java.launcher.pid
, которая доступна по крайней мере , на Linux. Мой план состоит в том, чтобы использовать это, и если не найдено, чтобы использоватьJMX bean
.источник
Это зависит от того, откуда вы ищете информацию.
Если вы ищете информацию из консоли, вы можете использовать команду jps. Команда выводит данные, аналогичные команде Unix ps, и поставляется с JDK, так как я считаю, что 1.5
Если вы смотрите на процесс, RuntimeMXBean (как сказал Wouter Coekaerts), вероятно, ваш лучший выбор. Вывод функции getName () в Windows с использованием Sun JDK 1.6 u7 имеет вид [PROCESS_ID] @ [MACHINE_NAME]. Однако вы можете попытаться выполнить jps и проанализировать результат из этого:
Если запустить без параметров, вывод должен быть идентификатор процесса, а затем имя.
источник
Это код JConsole, и, возможно, JPS и VisualVM использует. Он использует классы из
sun.jvmstat.monitor.*
пакета, изtool.jar
.Есть несколько уловов:
tool.jar
библиотека, распространяемая вместе с Oracle JDK, но не JRE!tool.jar
от репозитория Maven; настроить его с Maven немного сложнееtool.jar
, Вероятно , содержит зависимый (родной?) Код платформы , так что не легко распространяемыйОБНОВЛЕНИЕ: я только что дважды проверил, что JPS использует этот способ, то есть библиотека Jvmstat (часть tool.jar). Так что нет необходимости вызывать JPS как внешний процесс, напрямую вызывать библиотеку Jvmstat, как показывает мой пример. Вы также можете получить список всех JVM, запущенных на localhost. Смотрите исходный код JPS :
источник
Я добавляю это к другим решениям.
с Java 10, чтобы получить
process id
источник
Основываясь на ответе Эшвина Джаяпракаша (+1) о лицензированном Apache 2.0
SIGAR
, я использую его для получения только PID текущего процесса:Хотя он работает не на всех платформах, он работает на Linux, Windows, OS X и различных платформах Unix, как указано здесь .
источник
Вы можете попробовать
getpid()
в JNR-Posix .Он имеет оболочку Windows POSIX, которая вызывает getpid () из libc.
источник
Я знаю, что это старый поток, но я хотел сказать, что API для получения PID (а также другие манипуляции с процессом Java во время выполнения) добавляется в класс Process в JDK 9: http: // openjdk. java.net/jeps/102
источник
Я нашел решение, которое может показаться немного странным, и я не пробовал его на других ОС, кроме Windows 10, но, думаю, стоит обратить на это внимание.
Если вы обнаружите, что работаете с J2V8 и nodejs, вы можете запустить простую функцию javascript, возвращающую вам pid процесса java.
Вот пример:
источник
Вот мое решение:
источник
Это то, что я использовал, когда у меня было подобное требование. Это правильно определяет PID процесса Java. Позвольте вашему Java-коду порождать сервер по заранее определенному номеру порта, а затем выполнять команды ОС, чтобы выяснить PID, прослушивающий порт. Для Linux
источник
bash -c 'echo $PPID'
или ответы