[Java] 메모리 관리

2024. 2. 23. 09:28Web/JAVA

Java는 JVM이라는 가상머신에서 컴파일/실행 시키는것, JVM을 이해하여 자바의 메모리 할당부분 이해를 도운다.

 

JVM의 메모리 할당은 결국, Java Garbage Collection을 통해 메모리를 관리한다. Java의 GC에 대한 이해를 통해 메모리 관리에 대한 부분을 이해하자.

1. 일반적인 메모리의 구조

코드(code) 영역

메모리의 코드(code) 영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트(code) 영역이라고도 부릅니다. CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 됩니다.

 
데이터(data) 영역
메모리의 데이터(data) 영역은 프로그램의 전역 변수와 정적(static) 변수가 저장되는 영역입니다. 데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸합니다.
 
스택(stack) 영역
메모리의 스택(stack) 영역은 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역입니다. 스택 영역은 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸합니다. 스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출합니다. 
이러한 스택은 후입선출(LIFO, Last-In First-Out) 방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출됩니다. 스택 영역은 메모리의 높은 주소에서 낮은 주소의 방향으로 할당됩니다.
 
힙(heap) 영역
메모리의 힙(heap) 영역은 사용자가 직접 관리할 수 있는 '그리고 해야만 하는' 메모리 영역입니다.
힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제됩니다.
힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당됩니다.

 


2. Java의 메모리 관리

  • 인스턴스나 객체가 생성되는 경우에 Heap영역에 저장
  • Heap영역에 할당되었던 메모리는 사용되지 않더라도 자동으로 사라지지 않음
  • Stack 영역의 경우 메서드가 생성될 때 Stack프레임에 생성됐다가 메서드가 종료되면 해당 스택프레임이 자동 POP
  • Java 메모리의 Heap과 자료구조의 Heap은 다른 Heap임

3. Heap 영역의 구조

 

  • Heap영역의 경우 크게 Young Generation, Old Generation으로 나뉘어진다.
  • Young Generation
    • 인스턴스를 처음 생성하면 Young Generation에서 Eden 영역에 할당
    • Eden 영역이 꽉 차서 메모리를 할당할 수 없으면 Minor GC에 의해서 Eden 영역에 있는 요소 정리
    • GC(Garbage Collection)에 의해 정리된 데이터들은 Suvivor Space로 이동 (그 중 S0)
    • 다시 Eden 영역이 꽉차게 되면 Eden영역과 S0영역 GC 진행하고 S1 영역으로 복사
    • Eden 영역과 S0, S1 영역중 하나에 대한 Minor GC의 결과물을 Minor GC가 진행되지 않은 Survivor Space에 옮겨놓고 기존 영역들을 정리하는 방식
  • Old Generation
    • Young Generation에서 GC가 반복되는 과정에서 S0 영역과 S1 영역을 반복적으로 이동하는 데이터가 있음
    • 이 데이터들은 AGE가 증가하게 되고, 특정값 이상이 되면 Old Generation으로 이동하게 된다
    • 이렇게 Young영역에서 Old영역으로 이동하는 과정을 Promotion이라고 부른다.
    • Old영역에서 발생하는 GC를 Major GC라고 부른다.

4. Gabage Collection 동작 방식

  • 먼저 GC를 하기 위해 Stop The World 진행
  • Stop The World : Marking 작업을 위해서 모든 스레드를 중단
  • Mark & Sweep : 스레드를 멈추고 스택 내 지역변수 스캔(Mark) 한후, 참조가 되어있지 않은 오브젝트 Heap에서 제거(Sweep)