즐겁게/anything

JAVA 메모리 사용량 확인

파이브빈즈 2022. 10. 27. 13:26

현재 실행중인 Java application의 메모리 사용량을 확인해 볼 수 있다.

// JVM이 허용하는 최대 힙 메모리 크기, -Xmx
// long maxMem = Runtime.getRuntime().maxMemory()/1024/1024;
// 아래 내용(Runtime.getRuntime().maxMemory())을 보완하기위해 수정된 소스
long maxMem = 0L;
MemoryMXBean m = ManagementFactory.getMemoryMXBean();
for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
    if(mp.getName().indexOf("Tenured") > -1){
        maxMem += mp.getUsage().getMax();
    } else if(mp.getName().indexOf("Eden") > -1){
        maxMem += mp.getUsage().getMax();
    } else if(mp.getName().indexOf("Survivor") > -1){
    	// 곱하기 2를 해야 함(s0 + s1)
        maxMem += (mp.getUsage().getMax() * 2);
    }
}
if(maxMem == 0){
    // Runtime.getRuntime().maxMemory()와 -Xmx 값에는 약간의 차이가 발생
    // GC 구조 eden + survivor(s0 + s1) + tenured + parmanent 인데
    // xmx = eden + survivor(s0 + s1) + tenured(old gen)
    // maxMemory = eden + survivor/2 + tenured(old gen) : survivor 2개 중 한개가 빠짐
    maxMem = Runtime.getRuntime().maxMemory()/1024/1024;
}
// JVM이 현재 힙 메모리로 할당한 총 크기, -Xms (초기값) 및 힙 확장 상태
long totalMem = Runtime.getRuntime().totalMemory()/1024/1024;
// java vm이 추가로 할당 가능한 메모리
long freeMem = Runtime.getRuntime().freeMemory()/1024/1024;

// 현재 사용중인 메모리
long usedMem = totalMem - freeMem;
// 퍼센트
double pct = usedMem * 100 / maxMem;

String t = "heap.current \t heap.percent \t heap.max";
String s = String.format("%s\r\n%10dmb \t %11.1f%% \t %6dmb", t, usedMem, pct, maxMem);
System.out.println(s);

실행결과

그런데 실행한 결과를 보면 maxMemory가 -Xmx 지정한 사이즈보다 작은 값으로 표기된다.

JVM구조

maxMemory 는 GC 구조상 Eden + Survivor(s0 + s1)/2 + Old 로 계산되기 때문(survivor 2개중 한개만 계산에 포함)

아래의 링크를 참조: https://stackoverflow.com/questions/23701207/why-do-xmx-and-runtime-maxmemory-not-agree

 

Why do -Xmx and Runtime.maxMemory not agree

When you add -Xmx????m to the command line, the JVM gives you a heap which is close to this value but can be out by up to 14%. The JVM can give you a figure much closer to what you want, but o...

stackoverflow.com