Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 9 Process API로 시스템의 모든 프로세스 데이터 조회하는 방법

Java 9 Process API 개요

Java 9에서는 Process API가 대폭 개선되어 운영체제 수준의 프로세스를 훨씬 세밀하게 제어하고 관리할 수 있게 되었습니다. 이 버전에서 새롭게 도입된 ProcessHandle 인터페이스는 프로세스의 네이티브 프로세스 ID(PID), 시작 시간, 누적 CPU 사용 시간, 인수(arguments), 명령어(command), 사용자(user), 부모 프로세스, 그리고 자식(하위) 프로세스까지 폭넓은 정보를 제공합니다.

또한 isAlive() 메서드로 프로세스의 생존 여부(liveness)를 확인하거나, destroy() 계열 메서드로 프로세스를 종료하는 기능도 함께 제공됩니다. 무엇보다 ProcessHandle.allProcesses() 메서드를 호출하면 시스템에서 실행 중인 모든 프로세스를 Stream<ProcessHandle> 형태로 한 번에 가져올 수 있습니다.

전체 프로세스 정보 조회 예제

아래 예제는 실행 중인 모든 프로세스를 순회하면서 PID, 생존 여부, 자식 프로세스 수, 정상 종료 지원 여부, 그리고 Info 객체에 담긴 상세 정보를 차례로 출력합니다.

import java.util.Optional;
import java.util.stream.Stream;

public class AllProcessesTest {
    public static void main(String args[]) throws InterruptedException {
        System.out.println("---------------------------");
        System.out.println("All Processes:");
        Stream<ProcessHandle> processStream = ProcessHandle.allProcesses();
        processStream.forEach(process -> printInfo(process));
    }

    private static void printInfo(ProcessHandle processHandle) {
        System.out.println("---------");
        System.out.println("Id: " + processHandle.pid());
        System.out.println("isAlive(): " + processHandle.isAlive());
        System.out.println("number of children: " + processHandle.children().count());
        System.out.println("supportsNormalTermination(): " + processHandle.supportsNormalTermination());

        ProcessHandle.Info processInfo = processHandle.info();
        System.out.println("Info: " + processInfo.toString());
        System.out.println("Info arguments().isPresent(): " + processInfo.arguments().isPresent());
        System.out.println("Info command().isPresent(): " + processInfo.command().isPresent());
        System.out.println("Info totalCpuDuration().isPresent(): " + processInfo.totalCpuDuration().isPresent());
        System.out.println("Info user().isPresent(): " + processInfo.user().isPresent());
    }
}

핵심 메서드 정리

  • pid() : 해당 프로세스의 고유 식별자(PID)를 반환합니다.
  • isAlive() : 프로세스가 현재 실행 중인지 여부를 boolean 값으로 반환합니다.
  • children().count() : 자식 프로세스의 개수를 반환합니다.
  • supportsNormalTermination() : 일반적인 방식으로 프로세스를 정상 종료할 수 있는지 여부를 반환합니다.
  • info() : 명령어, 인수, 시작 시간, 누적 CPU 시간, 사용자 등의 상세 정보를 담은 ProcessHandle.Info 객체를 반환합니다.

info()가 반환하는 각 항목은 모두 Optional 타입입니다. 따라서 실제 값을 사용하기 전에 isPresent()로 존재 여부를 먼저 확인하는 것이 안전합니다. 이미 종료된 프로세스나 접근 권한이 없는 프로세스의 경우 빈(Optional.empty) 값이 반환됩니다.

실행 결과

실행 환경과 시점에 따라 출력되는 프로세스 목록은 달라지지만, Windows 환경에서 실행했을 때의 대표적인 결과는 다음과 같습니다.

---------------------------
All Processes:

Id: 7056
isAlive(): true
number of children: 0
supportsNormalTermination(): false
Info: [user: Optional[Tutorialspoint\User], cmd: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe, startTime: Optional[2020-03-09T03:26:00.406Z], totalTime: Optional[PT1M52.15625S]]
Info arguments().isPresent(): false
Info command().isPresent(): true
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
---------
Id: 7804
isAlive(): true
number of children: 4
supportsNormalTermination(): false
Info: [user: Optional[Tutorialspoint\User], cmd: C:\Program Files\Mozilla Firefox\firefox.exe, startTime: Optional[2020-03-09T03:30:51.441Z], totalTime: Optional[PT38.046875S]]
Info arguments().isPresent(): false
Info command().isPresent(): true
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
---------
(중략: 나머지 프로세스도 동일한 형식으로 출력됨)
---------
Id: 1032
isAlive(): false
number of children: 0
supportsNormalTermination(): false
Info: []
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): false
Info user().isPresent(): false

결과를 살펴보면 chrome.exe, firefox.exe, java.exe 등 실행 중인 각 프로세스마다 PID, 생존 여부, 자식 프로세스 수와 함께 user, cmd, startTime, totalTime 같은 상세 정보가 함께 출력되는 것을 확인할 수 있습니다. 특히 위 예시의 1032번 프로세스처럼 이미 종료된 프로세스는 isAlive()가 false이며 Info 정보도 모두 비어 있는 것을 볼 수 있습니다.