Java/일반

Java Heap 메모리 구조

창욱씨 2021. 8. 23. 01:15

Java 8 이전까지의 Heap 메모리 구조

Young

Young 영역은 Eden 영역과 Survivor 영역으로 구성됩니다. Eden 영역은 객체가 Heap에 최초로 할당되는 장소입니다. 만약 Eden 영역이 꽉 차게 되면 객체의 사용중 여부를 따져 만약 사용 중인 객체이면 Survivor 영역으로 넘기고, 사용 되지 않는 객체이면 그냥 남겨 둡니다. 사용 중인 모든 객체가 Survivor 영역으로 넘어가면 Eden 영역을 정리합니다.

Survivor 영역은 Eden에서 살아남은 객체들이 잠시 머무르는 공간입니다. Survivor 영역은 두 개로 구성되는데 참조 중인 객체를 이동할 때는 하나의 Survivor 영역만 사용하게 됩니다.

Old

Young 영역에서 정리되지 않고 계속 사용중인 객체들은 Old 영역으로 이동합니다. 즉, Old 영역은 새로 할당되는 객체가 아니라 비교적 오랫동안 사용되고 앞으로도 계속 사용될 확률이 높은 객체들이 저장되는 영역입니다.

Permanent

Permanent 영역은 보통 Class의 Meta 정보나 Method의 Meta 정보, Static 변수와 상수 정보들이 저장되는 공간입니다.

Java 8 이후의 Heap 메모리 구조

Metaspace

Permanent 영역이 MetaSpace 영역으로 전환되고 기존 Permanent 영역은 사라지게 되었습니다. 다만, 기존 Permanent 영역에 존재하던 Static Object는 Heap 영역으로 옮겨져 최대한 GC의 대상이 될 수 있도록 하였습니다. 참고로 MetaSpace 영역은 Heap 영역이 아니라 Native 메모리 영역으로 취급하게 됩니다. Native 메모리는 Heap과 달리 OS 레벨에서 관리하는 영역입니다.

우리가 WAS를 기동시키면 JVM이 초기화되고, 이후 각종 클래스 정보들이 로드되면서 해당 데이터들은 모두 Metaspace 영역으로 올라오게 됩니다. Java 8 버전 이전에는 Permanent 영역의 default 사이즈를 초과하거나 max로 지정한 수치를 초과하면 OOM이 발생하게 되었는데, Java 8 부터는 OS의 메모리를 사용하기 때문에 여유가 생겨서 따로 지정하지 않고, 필요에 따라 사이즈도 자동으로 증가하게 됩니다. 물론 max 수치를 지정할 수 있지만, 그냥 두는게 더 안전하다고 합니다.

Permanent 영역이 없어진 이유

기존의 Permanent 영역은 각종 Meta 정보와 Static 객체 정보들을 저장하고 있었습니다. 프레임워크의 사용으로 저장되는 Meta 정보의 양도 많아지고, Static 객체에 다양한 정보를 저장함에 따라 필요한 Permanent 영역의 크기가 증가하면서 OOM이 발생하지 않는 Permanent 영역의 크기를 예측하기 힘들어졌습니다. 이러한 불편함을 해소하기 위해 Meta 정보를 Native 영역으로 이동시킴으로서 OOM의 발생을 줄였습니다.

728x90