Как Java-программа может получить свой собственный идентификатор процесса? - PullRequest
328 голосов
/ 30 августа 2008

Как мне получить идентификатор моего процесса Java?

Я знаю, что есть несколько зависимых от платформы хаков, но я бы предпочел более общее решение.

Ответы [ 22 ]

6 голосов
/ 28 сентября 2016
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;
}
5 голосов
/ 13 апреля 2017
java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]
5 голосов
/ 05 сентября 2011

Последнее, что я обнаружил, - это системное свойство с именем sun.java.launcher.pid, которое доступно по крайней мере в Linux. Мой план состоит в том, чтобы использовать это, и если не найдено, использовать JMX bean.

4 голосов
/ 04 сентября 2008

Это зависит от того, откуда вы ищете информацию.

Если вы ищете информацию из консоли, вы можете использовать команду 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);

Если запустить без параметров, выводом должен быть идентификатор процесса, за которым следует имя.

2 голосов
/ 27 июня 2013

Это код 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;
    }
}

Есть несколько уловов:

  • 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 исходный код :

2 голосов
/ 11 февраля 2014

На основании ответа Эшвина Джаяпракаша (+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, как указано здесь .

1 голос
/ 01 сентября 2018

Я нашел решение, которое может показаться немного странным, и я не пробовал его на других ОС, кроме 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();
}
1 голос
/ 24 февраля 2018

Добавление к другим решениям.

с Java 10, чтобы получить process id

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);
1 голос
/ 11 марта 2015

Вы можете попробовать getpid() в JNR-Posix .

Имеется оболочка Windows POSIX, которая вызывает getpid () из libc.

1 голос
/ 25 июня 2015

Я знаю, что это старый поток, но я хотел вызвать, что API для получения PID (а также других манипуляций с процессом Java во время выполнения) добавляется в класс Process в JDK 9: http://openjdk.java.net/jeps/102

...