Java는 Garbage-Collection에 의해 메모리 관리가 진행되기 때문에 특별한 상황이 아니면 메모리에 대한 고민을 할 필요가 없다. 그런데 간만에 알고리즘 문제를 풀다가 메모리 초과를 만나고 난 후 마상을 입고 JVM의 Heap Memory에 대해 정리해본다.
런타임 메모리 설정
메모리 크기 확인하기
JVM의 Heap 메모리도 파고 들자면 구분과 동작이 매우 다양, 복잡하지만 일반적으로 프로그래머의 관심은 전체 메모리가 얼마이고 현재 얼마가 사용중이며 남은 메모리는 얼마인가 정보일 것이다.
이를 위해 java.lang.Runtime class에서는 totalMemory()와 freeMemory() 메서드를 제공하며 사용중인 메모리를 알기 위해서는 totalMemory() - freeMemory()를 사용하면 된다.
long total = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
System.out.println("used: " +((total-free)/1024/1024));
여기서 used는 현재 객체들이 사용하고 있는 메모리 공간이며 free는 앞으로 생성될 객체들이 사용할 공간, 그리고 이들을 합해서 total 메모리가 구성된다.
알고리즘 문제를 풀면서 만나는 메모리 제한은 바로 이 used memory에 대한 제한이다.
이 외에도 max 메모리라는 개념도 있는데 total 메모리에 추가로 사용 가능하도록 지정은 되었지만 아직 할당되지 않은 메모리(unlocated memory)를 합한 양이다.(이 값은 JVM 실행 옵션의 -Xmx로 지정된다.)
JVM 메모리 설정
JVM의 total memory는 고정된 값이 아니라 최초 생성된 크기에서 최대 크기까지 프로그램에서의 요청 사항에 따라 동적으로 변화한다.
JVM은 동작시 사용할 메모리 크기를 -Xms, -Xmn, -Xmx의 옵션을 통해서 설정받을 수 있다. 예를 들어 다음과 같은 설정이 있다고 생각해보자.
java -Xms20M -Xmn10M -Xmx50M ~~
-Xms는 JVM이 시작할 때(start) 20M의 heap 메모리를 할당한다는 이야기이다. 그래서 시작할 때 total memory는 20M가 되며 free memory는 "20-사용된 메모리"가 된다.
그러다 객체의 사용이 많아져서 보다 많은 heap memory가 필요해지면 -Xmx 옵션에 의해 최대 50m 까지 메모리를 추가로 확보하게 된다. 즉 -Xmx는 최대(max) 메모리를 나타내며 이때의 total memory는 50M로 늘어난다.