22 ответов:
не существует независимого от платформы способа, который может быть гарантирован для работы во всех реализациях jvm.
ManagementFactory.getRuntimeMXBean().getName()выглядит как лучшее (самое близкое) решение. Это коротко, и наверное работает в каждой реализации в широком использовании.в linux+windows он возвращает значение типа
12345@hostname(12345быть идентификатор процесса). Остерегайтесь, хотя это согласно документам, нет никаких гарантий относительно этого значения:возвращает имя представление виртуальной машины Java. Этот возвращаемая строка имени может быть любой произвольной строкой и виртуальная Java машинная реализация может выбрать для внедрения платформы конкретных полезных информация в строке возвращаемого имени. Каждая запущенная виртуальная машина может иметь другое имя.
В Java 9 новая process API можно использовать в:
long pid = ProcessHandle.current().pid();
вы могли бы использовать JNA. К сожалению, пока нет общего JNA API для получения текущего идентификатора процесса, но каждая платформа довольно проста:
Windows
убедитесь, что у вас есть
jna-platform.jarзатем:int pid = Kernel32.INSTANCE.GetCurrentProcessId();Unix
объявить:
private interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class); int getpid (); }затем:
int pid = CLibrary.INSTANCE.getpid();
Java 9
под Java 9 новый process API можно использовать для получения текущего идентификатора процесса. Сначала вы хватаете дескриптор текущего процесса, то запрос ПИД:
long pid = ProcessHandle.current().pid();
вот бэкдор метод, который может не работает со всеми виртуальными машинами, но должен работать как на linux, так и на windows (оригинальный пример здесь):
java.lang.management.RuntimeMXBean runtime = java.lang.management.ManagementFactory.getRuntimeMXBean(); java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm"); jvm.setAccessible(true); sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime); java.lang.reflect.Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId"); pid_method.setAccessible(true); int pid = (Integer) pid_method.invoke(mgmt);
попробовать сигар . очень обширный API-интерфейсы. Лицензией Apache 2.
private Sigar sigar; public synchronized Sigar getSigar() { if (sigar == null) { sigar = new Sigar(); } return sigar; } public synchronized void forceRelease() { if (sigar != null) { sigar.close(); sigar = null; } } public long getPid() { return getSigar().getPid(); }
следующий метод пытается извлечь PID из
java.lang.management.ManagementFactory:private static String getProcessId(final String fallback) { // Note: may fail in some JVM implementations // therefore fallback has to be provided // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs final String jvmName = ManagementFactory.getRuntimeMXBean().getName(); final int index = jvmName.indexOf('@'); if (index < 1) { // part before '@' empty (index = 0) / '@' not found (index = -1) return fallback; } try { return Long.toString(Long.parseLong(jvmName.substring(0, index))); } catch (NumberFormatException e) { // ignore } return fallback; }просто позвони
getProcessId("<PID>"), например.
вы можете проверить мой проект: JavaSysMon на GitHub. Он предоставляет идентификатор процесса и кучу других вещей (использование процессора, использование памяти) кросс-платформенный (в настоящее время Windows, Mac OSX, Linux и Solaris)
для старых JVM, в linux...
private static String getPid() throws IOException { byte[] bo = new byte[256]; InputStream is = new FileInputStream("/proc/self/stat"); is.read(bo); for (int i = 0; i < bo.length; i++) { if ((bo[i] < '0') || (bo[i] > '9')) { return new String(bo, 0, i); } } return "-1"; }
начиная с Java 9 существует метод Process.getPid (), который возвращает собственный идентификатор процесса:
public abstract class Process { ... public long getPid(); }чтобы получить идентификатор процесса текущего процесса Java можно использовать
ProcessHandleинтерфейс:System.out.println(ProcessHandle.current().pid());
для полноты есть обертка в Spring Boot на
String jvmName = ManagementFactory.getRuntimeMXBean().getName(); return jvmName.split("@")[0];решение. Если требуется целое число, то его можно суммировать до однострочного:
int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);Если кто-то уже использует Spring boot, он/она может использовать org.springframework.сапог.ApplicationPid
ApplicationPid pid = new ApplicationPid(); pid.toString();метод toString () выводит pid или '???'.
предостережения с использованием ManagementFactory обсуждаются в других ответах уже.
public static long getPID() { String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName(); if (processName != null && processName.length() > 0) { try { return Long.parseLong(processName.split("@")[0]); } catch (Exception e) { return 0; } } return 0; }
последнее, что я нашел, это то, что есть системное свойство под названием
sun.java.launcher.pidэто доступно, по крайней мере, на linux. Я планирую использовать это, и если это не использоватьJMX bean.
В Scala:
import sys.process._ val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLongЭто должно дать вам обходной путь в системах Unix до тех пор, пока Java 9 не будет выпущен. (Я знаю, вопрос был о Java, но поскольку для Scala нет эквивалентного вопроса, я хотел оставить это для пользователей Scala, которые могут наткнуться на тот же вопрос.)
Это зависит от того, где вы ищете информацию.
Если вы ищете информацию из консоли вы можете использовать команду JPS. Команда дает вывод, подобный команде Unix ps, и поставляется с JDK, так как я считаю 1.5
Если вы смотрите из процесса RuntimeMXBean (как сказал Wouter Coekaerts), вероятно, ваш лучший выбор. Выходные данные getName() в Windows с помощью Sun JDK 1.6 u7 представлены в виде [ИДЕНТИФИКАТОР_ПРОЦЕССА]@[ИМЯ_МАШИНЫ]. Однако вы можете попробовать выполнить jps и проанализировать результат от этого:
String jps = [JDK HOME] + "\bin\jps.exe"; Process p = Runtime.getRuntime().exec(jps);Если выполняется без параметров, вывод должен быть идентификатором процесса, за которым следует имя.
на основе Ашвина Джаяпракаша ответ (+1) о лицензированном Apache 2.0
SIGAR, вот как я использую его, чтобы получить только PID текущего процесса:import org.hyperic.sigar.Sigar; Sigar sigar = new Sigar(); long pid = sigar.getPid(); sigar.close();хотя он не работает на всех платформах, он работает на Linux, Windows, OS X и различные платформы Unix, как указано здесь.
это код JConsole, и потенциально использует jps и VisualVM. Он использует классы от
sun.jvmstat.monitor.*пакета изtool.jar.package my.code.a003.process; import sun.jvmstat.monitor.HostIdentifier; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.MonitoredHost; import sun.jvmstat.monitor.MonitoredVm; import sun.jvmstat.monitor.MonitoredVmUtil; import sun.jvmstat.monitor.VmIdentifier; public class GetOwnPid { public static void main(String[] args) { new GetOwnPid().run(); } public void run() { System.out.println(getPid(this.getClass())); } public Integer getPid(Class<?> mainClass) { MonitoredHost monitoredHost; Set<Integer> activeVmPids; try { monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null)); activeVmPids = monitoredHost.activeVms(); MonitoredVm mvm = null; for (Integer vmPid : activeVmPids) { try { mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString())); String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true); if (mainClass.getName().equals(mvmMainClass)) { return vmPid; } } finally { if (mvm != null) { mvm.detach(); } } } } catch (java.net.URISyntaxException e) { throw new InternalError(e.getMessage()); } catch (MonitorException e) { throw new InternalError(e.getMessage()); } return null; } }есть несколько зацепок:
- The
tool.jarэто библиотека, распространяемая с Oracle JDK, но не JRE!- вы не можете сделать
tool.jarиз РЕПО Maven; настроить его с помощью Maven немного сложно- The
tool.jarвероятно, содержит зависимый от платформы (родной?) код, так что это не легко распространяемый- он работает в предположении, что все (локальные) запущенные приложения JVM являются "контролируемыми". Похоже что из Java 6 Все приложения обычно есть (если вы активно не настраиваете противоположное)
- это, вероятно, работает только для Java 6+
- Eclipse не публикует основной класс, поэтому вы не получите Eclipse PID легко Ошибка в MonitoredVmUtil?
UPDATE: я только что дважды проверил, что JPS использует этот способ, то есть библиотеку Jvmstat (часть инструмент.сосуд.) Поэтому нет необходимости вызывать JPS как внешний процесс, вызовите библиотеку Jvmstat напрямую, как показывает мой пример. Вы также можете получить список всех JVMs, работающих на localhost таким образом. Смотрите JPS исходный код:
вы можете попробовать
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.
вот пример:
public static void main(String[] args) { NodeJS nodeJS = NodeJS.createNodeJS(); int pid = nodeJS.getRuntime().executeIntegerScript("process.pid;\n"); System.out.println(pid); nodeJS.release(); }
вот мое решение:
public static boolean isPIDInUse(int pid) { try { String s = null; int java_pid; RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean(); java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("@"))); if (java_pid == pid) { System.out.println("In Use\n"); return true; } } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } return false; }
добавлять к другим решениям.
С Java 10, чтобы получить
process idfinal RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); final long pid = runtime.getPid(); out.println("Process ID is '" + pid);
Это то, что я использовал, когда у меня были похожие требования. Это определяет PID процесса Java правильно. Пусть ваш java-код порождает сервер на заранее определенном номере порта, а затем выполняет команды ОС, чтобы узнать, что PID прослушивает порт. Для Linux
netstat -tupln | grep portNumber
Comments