Light Blue Pointer
본문 바로가기
Developing/TIL(Develop)

Java의 메모리 관리와 가비지 컬렉션

by Greedy 2024. 5. 16.

Java의 메모리 구조

힙 메모리(Heap Memory)

용도

객체와 배열이 저장되는 곳

동적으로 생성된 데이터가 저장됨

가비지 컬렉션의 주 대상

메모리 할당

런타임 시 동적으로 할당됨

new 키워드를 사용하여 객체를 생성할 때 사용됨

생명 주기

힙 메모리에 할당된 객체는 프로그램 전체 실행 기간 동안 존재할 수 있다

가비지 컬렉터에 의해 더 이상 참조되지 않는 객체는 자동으로 해제된다

관리

JVM이 관리하며, 가비지 컬렉션을 통해 자동으로 메모리를 해제한다

수동으로 메모리를 해제할 필요가 없다

크기

일반적으로 스택 메모리보다 크며, 제한된 크기 안에서 동적으로 확장될 수 있다

스택 메모리(Stack Memory):

용도

메서드 호출 시 생성되는 지역 변수와 함수 호출 정보를 저장한다

메서드의 실행 컨텍스트(프레임)가 저장된다

메모리 할당

컴파일 타임에 결정되며, 메서드가 호출될 때마다 자동으로 할당된다

메서드 호출이 끝나면 메모리가 자동으로 해제된다

생명 주기

스택 메모리에 할당된 변수는 해당 메서드가 실행되는 동안만 존재한다

메서드가 종료되면 해당 스택 프레임이 제거된다

관리

LIFO(Last In, First Out) 방식으로 관리되며, 개발자가 직접 관리하지 않아도 된다

메모리 누수나 가비지 컬렉션과 관련이 없다

크기

일반적으로 힙 메모리보다 작으며, 스레드마다 별도의 스택이 할당된다

가비지 컬렉션 (Garbage Collection)

자바 가상 머신(JVM)에서 더 이상 참조되지 않는 객체를 자동으로 메모리에서 해제하는 메커니즘

개발자가 명시적으로 메모리를 해제하지 않아도 되므로 메모리 누수(memory leak) 문제를 줄일 수 있게 된다

주요 가비지 컬렉터

  1. Serial GC
    • 단일 스레드로 동작한다
    • 작은 애플리케이션에 적합하다
  2. Parallel GC
    • 여러 스레드를 사용하여 가비지 컬렉션 작업을 병렬로 처리한다
    • 멀티코어 시스템에 적합하다
  3. CMS (Concurrent Mark-Sweep) GC
    • 애플리케이션의 멈춤 시간을 최소화하려고 설계되었다
    • 동시에 여러 스레드를 사용하여 가비지 컬렉션을 수행한다
  4. G1 (Garbage First) GC
    • 힙 메모리를 여러 개의 영역(region)으로 나눠 관리한다
    • 예측 가능한 짧은 멈춤 시간을 제공한다
    • 큰 힙을 가진 애플리케이션에 적합하다

가비지 컬렉션 동작 원리

가비지 컬렉션 기본 단계

마킹(Marking)

JVM이 힙 메모리의 모든 객체를 검사하여 여전히 참조되고 있는 객체와 그렇지 않은 객체를 식별한다

살아 있는 객체는 마크(mark)되고, 죽은 객체는 마크되지 않는다

스위핑(Sweeping)

마크되지 않은 객체를 제거

이 단계에서 메모리를 해제하고, 해당 메모리 공간을 다시 사용할 수 있도록 한다

압축(Compacting)

메모리 단편화(fragmentation)를 줄이기 위해 살아 있는 객체를 힙 메모리의 한쪽으로 모은다

메모리 할당을 연속된 공간에서 수행할 수 있도록 하여 성능을 향상시킨다

Stop-the-world

가비지 컬렉션이 수행되는 동안 애플리케이션의 실행을 멈춘다

중단 시간 동안 JVM은 안전하게 객체를 검사하고 제거한다

이는 가비지 컬렉션이 애플리케이션의 성능에 영향을 줄 수 있는 이유 중 하나이다

Generational Garbage Collection

힙 메모리를 세대(Generation)로 나눠 관리한다

일반적으로 Young Generation과 Old Generation으로 나눈다

Young Generation은 주로 짧은 수명을 가진 객체를 저장한다

Old Generation은 오래된 객체를 저장한다

Young Generation은 다시 Eden Space와 Survivor Space로 나뉜다

대부분의 객체는 Eden에서 생성되고, 일정 시간이 지나면 Survivor Space로 이동한다

오래 살아남은 객체는 Old Generation으로 이동한다

가비지 컬렉션 튜닝

JVM 옵션 설정

Xms와 Xmx 옵션을 사용하여 힙 메모리의 초기 크기와 최대 크기를 설정할 수 있다

XX:+UseG1GC와 같은 옵션을 사용하여 특정 가비지 컬렉터를 선택할 수 있다

객체 생명 주기 관리

불필요한 객체 생성을 피하고, 가능한 객체 재사용을 통해 메모리 사용을 최적화한다

메모리 누수를 방지하기 위해 객체 참조를 명시적으로 null로 설정하거나, WeakReference를 사용한다

프로파일링 도구 사용

VisualVM, YourKit 등과 같은 도구를 사용하여 메모리 사용을 모니터링하고, 잠재적인 문제를 식별하여 최적화한다

자바의 메모리 관리와 가비지 컬렉션은 자동화되어 있지만, 애플리케이션의 성능을 개선하고 메모리 문제를 방지하기 위해 최적화하는 것이 중요하다.