The primary goal of the developers is, to make it easier for you to manage processes on your operating system. They start with giving you the ability to enumerate the system processes via the updated API (no hacky solutions anymore). That means, you can get different properties for each process, e.g. the PID, the process name, the user who started it, the path of the process, resource usage, etc. It is also planned, to make it easier to deal with process trees, especially destructing entire process trees and managing processes with over 100 sub-processes. To do so, it is planned to multiplex their output streams into one output stream, so you do no longer have one thread per monitored process listening for its output stream
How would it look like
We have two examples for you. In the first example, one tries to get the process-id of the current process. In the second example, one tries to get a list of all processes.
So let’s see, how retrieving the process-ID of the current process looks like, before the ProcessAPI-Update.
private static int getProcessOwnID() {
// pName is equal to PID@COMPUTER_NAME
String pName = ManagementFactory.getRuntimeMXBean().getName();
return Integer.parseInt(pName.split("@")[0]);
}
So let’s see, how retrieving the process-ID of the current process looks like, before the ProcessAPI-Update.
private static int getProcessOwnID() {
// pName is equal to PID@COMPUTER_NAME
String pName = ManagementFactory.getRuntimeMXBean().getName();
return Integer.parseInt(pName.split("@")[0]);
}
As you can see, the name is retrieved via the runtime-mx-bean. This returns a String which looks like 1234@Some_Computer. So the String is splitten and the number left of the ‘@’ is converted to an Integer. Very hacky.
How would it look like with the new API?
private static int getOwnProcessID(){
return ProcessHandle.current().getPid();
}
Much more beautiful, isn’t it?
As you can see, you do not need any more String-Splitting. The new class “ProcessHandle” contains a static method “current”, which returns you an instance of ProcessHandle representing a handle for the current process. This handle-object contains various information about the process it is attached to. This includes handles to the sub-processes, its process-id and an internal info-object containing more detailed information about the process.
Now let’s see a slightly more complex example, where one is getting a list of all processes running on the operating system.
This is an old implementation with pure Java:
return ProcessHandle.current().getPid();
}
Much more beautiful, isn’t it?
As you can see, you do not need any more String-Splitting. The new class “ProcessHandle” contains a static method “current”, which returns you an instance of ProcessHandle representing a handle for the current process. This handle-object contains various information about the process it is attached to. This includes handles to the sub-processes, its process-id and an internal info-object containing more detailed information about the process.
Now let’s see a slightly more complex example, where one is getting a list of all processes running on the operating system.
This is an old implementation with pure Java:
// for Windows:
private static void doStuffWithProcesses() {
try {
Process p = Runtime.getRuntime().exec(
System.getenv("windir") + "\\system32\\tasklist.exe");
private static void doStuffWithProcesses() {
try {
Process p = Runtime.getRuntime().exec(
System.getenv("windir") + "\\system32\\tasklist.exe");
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = input.readLine()) != null) {
System.out.println(line);
//If line describes a correct process,
//reformat the string to get your information out here.
}
input.close();
System.out.println(line);
//If line describes a correct process,
//reformat the string to get your information out here.
}
input.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
ioe.printStackTrace();
}
}
As you see in lines 4ff, a program delivered with Windows called “tasklist.exe” is executed. This programs output stream is read (lines 7ff).
Very hacky, isn’t it? It works only for Windows and so have to use a slightly different solution for every operating system. And this snippet does not contain the Pattern-Regex that you need to get some valuable information out of the stream in line 11, because the output looks like this:
Very hacky, isn’t it? It works only for Windows and so have to use a slightly different solution for every operating system. And this snippet does not contain the Pattern-Regex that you need to get some valuable information out of the stream in line 11, because the output looks like this:
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== =============
System Idle Process 0 Services 0 4K
System 4 Services 0 10.604K
csrss.exe 504 Services 0 2.792K
wininit.exe 572 Services 0 2.900K
svchost.exe 808 Services 0 18.568K
(...)
========================= ======== ================ =========== =============
System Idle Process 0 Services 0 4K
System 4 Services 0 10.604K
csrss.exe 504 Services 0 2.792K
wininit.exe 572 Services 0 2.900K
svchost.exe 808 Services 0 18.568K
(...)
You would also have to adjust this regex for every operating system, too.
But now look at
But now look at
private static void listProcesses(){
ProcessHandle.allProcesses().forEach((h) -> printHandle(h));
}
private static void printHandle(ProcessHandle procHandle) {
ProcessHandle.allProcesses().forEach((h) -> printHandle(h));
}
private static void printHandle(ProcessHandle procHandle) {
// get info from handle
ProcessHandle.Info procInfo = procHandle.info();
System.out.println("PID: " + procHandle.getPid());
System.out.print("Start Parameters: ");
String[] empty = new String[]{"-"};
for (String arg : procInfo.arguments().orElse(empty)) {
System.out.print(arg + " ");
}
System.out.println();
System.out.println("Path: " + procInfo.command().orElse("-"));
System.out.println("Start: " + procInfo.startInstant().
orElse(Instant.now()).toString());
System.out.println("Runtime: " + procInfo.totalCpuDuration().
orElse(Duration.ofMillis(0)).toMillis() + "ms");
System.out.println("User: " + procInfo.user());
}
ProcessHandle.Info procInfo = procHandle.info();
System.out.println("PID: " + procHandle.getPid());
System.out.print("Start Parameters: ");
String[] empty = new String[]{"-"};
for (String arg : procInfo.arguments().orElse(empty)) {
System.out.print(arg + " ");
}
System.out.println();
System.out.println("Path: " + procInfo.command().orElse("-"));
System.out.println("Start: " + procInfo.startInstant().
orElse(Instant.now()).toString());
System.out.println("Runtime: " + procInfo.totalCpuDuration().
orElse(Duration.ofMillis(0)).toMillis() + "ms");
System.out.println("User: " + procInfo.user());
}
No comments:
Post a Comment