Java 9에서는 프로세스 처리(Process Handling) 관련 클래스와 새로운 API가 도입되었습니다. ProcessHandle 인터페이스와 이에 포함된 다양한 메서드를 활용하면 현재 실행 중인 프로세스의 PID뿐만 아니라 다른 관련 프로세스들의 상세 정보도 손쉽게 확인할 수 있습니다.
특정 프로세스의 모든 자식(child) 프로세스를 가져오고 싶다면 java.lang.ProcessHandle.children() 메서드를 사용하면 됩니다. 이 메서드는 해당 프로세스의 자식 프로세스들을 Stream 형태로 반환하며, 만약 자식 프로세스가 존재하지 않는다면 일반적으로 빈 스트림을 반환합니다.
예제 코드
아래 예제에서는 시스템에서 첫 번째 프로세스를 찾은 뒤, 해당 프로세스의 자식 프로세스 정보(PID와 실행 명령어)를 출력하는 방법을 보여줍니다.
import java.util.stream.Stream;
import java.util.Optional;
public class ChildrenProcessTest {
public static void main(String args[]) throws InterruptedException {
System.out.println("---------------------------");
System.out.println("Children Processes:");
Optional<ProcessHandle> processHandle = ProcessHandle.allProcesses().findFirst();
processHandle.ifPresent(proc -> proc.children().forEach(
child -> System.out.println(
"PID: [ " + child.pid() + " ], Cmd: [ " + child.info().command() + " ]"
)
));
}
}실행 결과
--------------------------- Children Processes: PID: [ 0 ], Cmd: [ Optional.empty ] PID: [ 4 ], Cmd: [ Optional.empty ] PID: [ 424 ], Cmd: [ Optional.empty ] PID: [ 504 ], Cmd: [ Optional.empty ] PID: [ 560 ], Cmd: [ Optional.empty ] PID: [ 444 ], Cmd: [ Optional.empty ] PID: [ 1236 ], Cmd: [ Optional.empty ] PID: [ 1288 ], Cmd: [ Optional.empty ] PID: [ 1408 ], Cmd: [ Optional.empty ] PID: [ 1424 ], Cmd: [ Optional.empty ] PID: [ 1452 ], Cmd: [ Optional.empty ] PID: [ 1468 ], Cmd: [ Optional.empty ] PID: [ 5412 ], Cmd: [ Optional[C:\WINDOWS\System32\taskhostex.exe] ] PID: [ 3760 ], Cmd: [ Optional[C:\Program Files\Synaptics\SynTP\SynTPEnh.exe] ] PID: [ 5216 ], Cmd: [ Optional[C:\WINDOWS\explorer.exe] ] PID: [ 2460 ], Cmd: [ Optional[C:\Program Files (x86)\Dell Wireless\Bluetooth Suite\BtvStack.exe] ] PID: [ 6064 ], Cmd: [ Optional[C:\Program Files\Realtek\Audio\HDA\RtkNGUI64.exe] ] PID: [ 7172 ], Cmd: [ Optional[C:\Program Files (x86)\Google\Chrome\Application\chrome.exe] ] PID: [ 860 ], Cmd: [ Optional[C:\Program Files (x86)\Google\Chrome\Application\chrome.exe] ] PID: [ 9000 ], Cmd: [ Optional.empty ] PID: [ 4180 ], Cmd: [ Optional[C:\WINDOWS\System32\cmd.exe] ] PID: [ 3748 ], Cmd: [ Optional[C:\WINDOWS\System32\conhost.exe] ] PID: [ 3376 ], Cmd: [ Optional.empty ] PID: [ 2548 ], Cmd: [ Optional.empty ] PID: [ 1820 ], Cmd: [ Optional[C:\Program Files\Java\jdk-9.0.4\bin\java.exe] ]
코드 설명
위 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.
1. 전체 프로세스 조회: ProcessHandle.allProcesses() 메서드는 현재 시스템에서 실행 중인 모든 프로세스의 핸들을 스트림으로 반환합니다. 여기에 findFirst()를 호출하여 첫 번째 프로세스 핸들을 Optional<ProcessHandle> 객체로 받아옵니다.
2. 자식 프로세스 순회: ifPresent()를 통해 프로세스 핸들이 실제로 존재하는 경우에만 안전하게 처리를 진행합니다. 이후 children() 메서드가 반환하는 스트림을 forEach()로 순회하며 각 자식 프로세스의 정보를 출력합니다.
3. 프로세스 정보 추출: 각 자식 프로세스에 대해 child.pid()로 프로세스 ID를, child.info().command()로 실행 명령어 경로를 가져옵니다. 명령어 정보는 Optional 타입으로 반환되기 때문에, 접근 권한이 없거나 정보를 얻을 수 없는 프로세스의 경우 Optional.empty가 출력됩니다.
이처럼 Java 9의 Process API를 활용하면 운영체제에 종속적인 네이티브 코드 없이도 순수 Java만으로 프로세스 계층 구조를 탐색하고 관리할 수 있습니다. 프로세스 모니터링 도구나 작업 관리자 유형의 애플리케이션을 개발할 때 매우 유용하게 활용될 수 있습니다.