본문 바로가기
Java

[Java] ScheduledExecutorService로 JVM 메모리 사용량 모니터링하기

by teamnova 2025. 4. 2.
728x90

 

안녕하세요 오늘은 JVM 의 현재 메모리 사용량을 3초 간격으로 출력하여 확인해보도록 하겠습니다.

현대 소프트웨어 환경에서는 대부분 동시에 여러작업을 처리해야하는 상황이 늘 생깁니다.

 

예를 들어, 웹 서버가 여러 사용자의 요쳥을 동시에 처리한다거나, 채팅 앱이 백그라운드로 메시지를 계속 주고 받을 때,

앱이 ui 는 유지하면서 백그라운드 작업을 해야할때 반드시 멀티 스레딩이나 비동기 프로그램이 필요합니다. 자바에서는 Thread 클래스, Runnable 인터페이스 구현을 지원하지만 이는 스레드를 직접 관리해야하며, 메모리 낭비로 이어지기 쉽습니다.

 

이를 보완하기 위해 오늘날 자바에는 java.util.concurrent 패키지를 제공합니다. 해당 패키지를 통해 병렬처리, 스케줄링, 스레드 풀 자동 관리,비동기 작업을 훨씬 안정적이고 효율적으로 할 수 있게 되었습니다.

 

 

해당 패키지에는 아래 내용에 있습니다.

주요 클래스/ 인터페이스  설명
 Executor / ExecutorService  작업을 실행해주는 인터페이스 (스레드 풀 기반) 
ScheduledExecutorService  일정 시간 후 or 주기적으로 작업 실행 
Future, Callable  비동기 작업 결과를 다루기 위한 객체 
CountDownLatch, Semaphore, Lock 등 동기화 도구들
ConcurrentHashMap   멀티스레드 환경에서 안전하게 쓰는 Map

 

  위 내용 중 ScheduledExecutorService 를 사용하여

JVM 의 현재 메모리 사용량, JVM 이 할당 받은 전체 메모리, 사용 가능한 남은 메모리를 일정 시간 간격(3초) 으로 확인하는 스레드를 만들어보겠습니다.

 

 

 

1. Main.java

import java.util.concurrent.Executors; // 아래 ScheduledExecutorService 의 인스턴스를 쉽게 만들어주는 클래스 (유틸 클래스, 보조자 역할)
import java.util.concurrent.ScheduledExecutorService; // 반복 작업, 예약 작업 등을 스케줄링하는 역할을 하는 인터페이스. (메소드:scheduleAtFixedRate, scheduleWithFixedDelay, ... 등)
import java.util.concurrent.TimeUnit; // 시간 단위 표현, 시간 계산, 지연 작업, 등 수행할 수 있게함.


public class Main {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        scheduler.scheduleAtFixedRate(() -> {
            // 현재 JVM의 메모리 정보 가져오기
            Runtime runtime = Runtime.getRuntime();

            long totalMemory = runtime.totalMemory();   // JVM이 확보한 전체 메모리
            long freeMemory = runtime.freeMemory();     // 그 중에서 아직 사용되지 않은 메모리
            long usedMemory = totalMemory - freeMemory; // 실제 사용 중인 메모리

            System.out.println("====== 메모리 사용 현황 ======");
            System.out.println("사용 중: " + bytesToMB(usedMemory) + " MB");
            System.out.println("남은 메모리: " + bytesToMB(freeMemory) + " MB");
            System.out.println("전체 확보 메모리: " + bytesToMB(totalMemory) + " MB");
            System.out.println();

        }, 0, 3, TimeUnit.SECONDS);
    }


    private static long bytesToMB(long bytes) {
        return bytes / (1024 * 1024);
    }
}

 

- concurrent 패키지 안에 있는 클래스 중 필요한 클래스를 상단에 import 해줍니다

- 현재 메모리(jvm) 정보를 가져와서 상세 내용을 출력합니다.

- 3초 간격으로 (TimeUnit.SECONDS) 메모리 사용 현황이 출력됩니다.

 

 

2. 출력 결과 (3초에 "메모리 사용 현황" 한 블럭씩 출력됨)

====== 메모리 사용 현황 ======
사용 중: 6 MB
남은 메모리: 501 MB
전체 확보 메모리: 508 MB

====== 메모리 사용 현황 ======
사용 중: 6 MB
남은 메모리: 501 MB
전체 확보 메모리: 508 MB

====== 메모리 사용 현황 ======
사용 중: 6 MB
남은 메모리: 501 MB
전체 확보 메모리: 508 MB

====== 메모리 사용 현황 ======
사용 중: 6 MB
남은 메모리: 501 MB
전체 확보 메모리: 508 MB

 

이처럼 java.util.concurrent 패키지를 활용하면 복잡한 스레드 관리 없이도 주기적인 작업, 병렬 실행, 동기화 문제를 보다 안정적으로 해결할 수 있습니다.

위 예제를 통해 ScheduledExecutorService의 기본적인 사용 방법과 JVM 메모리 모니터링의 간단한 구현 예시를 확인해 보았습니다.

 

감사합니다