Как программа Java может получить свой собственный идентификатор процесса?
Как получить идентификатор моего Java-процесса?
Я знаю, что есть несколько зависящих от платформы хаков, но я бы предпочел более общее решение.
- Как получить PID фонового процесса?
- Найти мой собственный идентификатор процесса в VBScript
- Как получить PID процесса, который я только начал в java-программе?
- Как захватить PID процесса при его запуске из командной строки?
- Не удалось подключиться к идентификатору процесса Xcode
- Нет необходимости экспортировать при запуске функций в подоболочке
- Как проверить, существует ли идентификатор процесса (PID)
- Как проверить, существует ли процесс с данным pid в Python?
- Исключение grep из списка процессов
- Как убить сессию ssh, связанную с созданием / отключением?
- Как убить одну вкладку google chrome с помощью pid
- Пакет PID приложения IIS
- PID: 4 с использованием порта 80
Не существует независимого от платформы способа, который может быть гарантирован для работы во всех реализациях jvm. ManagementFactory.getRuntimeMXBean().getName()
выглядит как лучшее (самое близкое) решение. Он короткий и, вероятно, работает в каждой реализации в широком использовании.
В linux + windows он возвращает значение, подобное [email protected]
( 12345
– идентификатор процесса). Остерегайтесь, хотя в соответствии с документами нет никаких гарантий относительно этого значения:
Возвращает имя, представляющее запущенную виртуальную машину Java. Возвращенная строка имени может быть любой произвольной строкой, а реализация виртуальной машины Java может вставлять полезную информацию, относящуюся к платформе, в возвращаемой строке имени. Каждая работающая виртуальная машина может иметь другое имя.
В Java 9 можно использовать новый API процесса :
long pid = ProcessHandle.current().pid();
Вы можете использовать JNA . К сожалению, нет единого API-интерфейса JNA для получения текущего идентификатора процесса, но каждая платформа довольно проста:
Windows
Убедитесь, что у вас есть jna-platform.jar
затем:
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
Юникс
Объявляет:
private interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class); int getpid (); }
Затем:
int pid = CLibrary.INSTANCE.getpid();
Java 9
В Java 9 новый API процесса может использоваться для получения текущего идентификатора процесса. Сначала вы берете дескриптор текущего процесса, затем запрашиваете PID:
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 '@', 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("
, например.
Вы можете проверить мой проект: 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.boot.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
.
В Скала:
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 находится в форме [PROCESS_ID] @ [MACHINE_NAME]. Однако вы можете попытаться выполнить jps и проанализировать результат:
String jps = [JDK HOME] + "\\bin\\jps.exe"; Process p = Runtime.getRuntime().exec(jps);
Если запустить без параметров, то результатом должен быть идентификатор процесса, за которым следует имя.
Основываясь на ответе Ashwin Jayaprakash (+1) об лицензированном SIGAR
Apache 2.0, вот как я использую его, чтобы получить только PID текущего процесса:
import org.hyperic.sigar.Sigar; Sigar sigar = new Sigar(); long pid = sigar.getPid(); sigar.close();
Несмотря на то, что он не работает на всех платформах, он работает в Linux, Windows, OS X и различных платформах Unix, перечисленных здесь .
java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]
Это код JConsole, и, возможно, использует jps и VisualVM. Он использует classы от sun.jvmstat.monitor.*
tool.jar
, from 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 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; } }
Есть немного уловов:
-
tool.jar
– это библиотека, распространяемая с Oracle JDK, но не JRE! - Вы не можете получить
tool.jar
из Maven repo; настроить его с помощью Maven немного сложно - Инструмент
tool.jar
вероятно, содержит зависимый от платформы (native?) Код, поэтому он нелегко распределяется - Он исходит из предположения, что все (локальные) JVM-приложения «контролируются». Похоже, что с Java 6 все приложения обычно (если вы не настроите их на противоположную)
- Вероятно, он работает только для Java 6+
- Eclipse не публикует основной class, поэтому вы не получите Eclipse PID легко Ошибка в MonitoredVmUtil?
UPDATE: Я только дважды проверил, что JPS использует этот путь, то есть библиотеку Jvmstat (часть инструмента tool.jar). Поэтому нет необходимости вызывать JPS в качестве внешнего процесса, вызывать библиотеку Jvmstat непосредственно, как показывает мой пример. Вы также можете получить список всех JVM runnin на localhost таким образом. См. Исходный код JPS:
Вы можете попробовать getpid()
в JNR-Posix .
У этого есть shell Windows POSIX, которая вызывает getpid () от libc.
Я знаю, что это старый stream, но я хотел бы назвать, что API для получения PID (а также других манипуляций с процессом Java во время выполнения) добавляется в class Process в JDK 9: http: // openjdk. java.net/jeps/102
Вот мое решение:
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 id
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); final long pid = runtime.getPid(); out.println("Process ID is '" + pid);
Я нашел решение, которое может быть немного кромкой, и я не пробовал его на другой ОС, чем 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(); }
Это то, что я использовал, когда у меня было подобное требование. Это правильно определяет PID процесса Java. Пусть ваш Java-код порождает сервер по предварительно определенному номеру порта, а затем выполняет команды ОС, чтобы узнать, что PID прослушивает порт. Для Linux
netstat -tupln | grep portNumber