How do I get the id of my Java process?
I know there are several platform-dependent hacks, but I would prefer a more generic solution.
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;
}
The following method tries to extract the PID from 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;
}
Just call getProcessId("<PID>")
, for instance.
Based on Ashwin Jayaprakash's answer (+1)
about the Apache 2.0 licensed SIGAR
, here is how I use it to get only the PID of the current process:
import org.hyperic.sigar.Sigar;
Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();
Even though it does not work on all platforms, it does work on Linux, Windows, OS X and various Unix platforms as listed here.
You could use JNA. Unfortunately there is no common JNA API to get the current process ID yet, but each platform is pretty simple:
Make sure you have jna-platform.jar
then:
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
Declare:
private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
int getpid ();
}
Then:
int pid = CLibrary.INSTANCE.getpid();
Under Java 9 the new process API can be used to get the current process ID. First you grab a handle to the current process, then query the PID:
long pid = ProcessHandle.current().pid();
Here's a backdoor method which might not work with all VMs but should work on both linux and windows (original example here):
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);
You can check out my project: JavaSysMon on GitHub. It provides process id and a bunch of other stuff (CPU usage, memory usage) cross-platform (presently Windows, Mac OSX, Linux and Solaris)