JAVA) JVM 의 쓰레기처리장 Garbage Collection(GC)란

백준우·2022년 12월 27일
0

Java & Spring

목록 보기
3/6
post-thumbnail
post-custom-banner

1. Garbage Collection

  1. Garbage Collection이란?
  2. 예제코드
  3. JVM의 Garbage Collection
  4. Garbage Collection의 동작방식

들어가면서

  • JS로 코드를 짤때는 워낙 방법이 쉽고 데이터의 남발이나 메모리에 대한 걱정이 없었다.
  • 하지만 JAVA로 넘어오면서 정적인 데이터와 정형화된 코드를 위해 메모리에 대해 생각하고 염두를 해야겠다고 생각했다.
  • 학습중 JVM에서 메모리를 정리해주는 GC에대해 알게되었고 100%는 아니나 로직과 flow에 대해서 학습을 하고자 했다.


<출처 - https://coding-factory.tistory.com/829 >

1. Garbage Collection

  1. Garbage Collection이란?
  • 프로그램을 개발 하다 보면 유효하지 않은 메모리인 가바지(Garbage)가 발생하게 된다.
  • 하지만 Java는 개발자가 메모리를 직접 해제해주는 일이 없다. JVM의 가비지 컬렉터가 불필요한 메모리를 알아서 정리해주기 때문이다.
  1. 예제코드
Person person = new Person();
person.setName("Baek");
person = null;

// 가비지 발생
person = new Person();
person.setName("joon");
  • 기존의 Baek으로 생성된 person 객체는 더이상 참조하지 않고 Garbage가 되었다.
  • Java에서는 System.gc()를 이용해 호출하여 메모리누수를 방지하기 위한 가비지컬렉터를 할 수 있다.
  • 해당 메소드를 호출하는 것은 시스템의 성능에 매우 큰 영향을 미치므로 절대 호출해서는 안된다.
  1. JVM의 Garbage Collection
  • JVM의 Heap은 설계될떄 2가지를 전제로 설계가 되었다.
    1) 대부분의 객체는 금방 접근 불가능한 상태가 된다.
    2) 오래된 객체에서 새로운 객체로의 참고는 극히 적은 상황이다.

즉, 객체는 대부분 일회성이며, 메모리에 오랫동안 남아있는 경우는 드물다. 그렇기 때문에 객체의 생존기간에 따라 물리적인 Heap영역을 나누게 되었고 이는 Young, Old로 나누어서 설계되었다.

<출처 - https://mangkyu.tistory.com/118 >

  • Young Generations
    1) 생명 주기가 짧은 “젊은 객체”를 GC 대상으로 하는 영역이다.
    2) 두개의 Survivor space가 존재
    3) 해당 영역에서 발생되는 GC를 Minor GC 라고 하며 Major GC에 비해 속도가 빠르다.
  • Old Generation
    1) 생명 주기가 긴 “오래된 객체”를 GC 대상으로 하는 영역이다.
    2) 해당 영역에서 발생되는 GC를 Major GC 라고 하며 Minor GC에 비해 속도가 느리다.

Old 영역이 Young영역보다 크게 설계되었는데 이유는 Young에 수명이 짧은 객체들은 큰 공간을 필요로 하지 않으며 큰 객체들은 Young영역이 아니라 바로 Old에 할당되기 때문이다.

보통은 Young영역이 Old영역을 참조하는 환경이겠으나 예외적으로 Old 영역에 있는 객체가 Young 영역의 객체를 참조하는 경우도 존재할 것이다. 이러한 경우를 대비해서 Old영역에는 512 Byte로 각각 할당된 Card Table이 존재한다. Young 영역에서 가비지 컬렉션이 진행될 때 카드 테이블만 조회하여 GC의 대상인지 식별할 수 있도록 하고 있다.

<출처 - https://mangkyu.tistory.com/118 >

  1. Garbage Collection의 동작방식은 Old와 Young의 구조가 다르기 때문에 세부적인 동작방식은 다르다, 하지만 기본적으로 2가지 공통적인 단계를 따르게 된다.
    1) Stop the world : JVM이 어플리케이션의 실행을 멈추는 작업, GC를 실행할땐 GC의 스레드를 제외한 모든 스레드의 작업이 중단된다.
    2) Mark and Sweep : Mark는 사용되는 메모리와 사용되지 않는 메모리를 식별하는단계 , Sweep는 Mark단계에서 사용되지 않음으로 식별된 메모리를 해체하는 작업이다.
  • Young영역에는 1개의 Eden영역과 2개의 Survivor 영역으로 나뉜다.
    1) Eden : 새로 생성된 객체가 할당 되는 영역
    2) Survivor : 최소 1번의 GC이상 살아남은 객체가 존재하는 영역
  • Minor GC
    객체가 새롭게 생성되면 Young 영역 중에서도 Eden 영역에 할당(Allocation)이 된다. 그리고 Eden 영역이 꽉 차면 Minor GC가 발생하게 되는데, 사용되지 않는 메모리는 해제되고 Eden 영역에 존재하는 객체는 (사용중인) Survivor 영역으로 옮겨지게 된다.
  • Major GC
    Young 영역에서 오래 살아남은 객체는 Old 영역으로 Promotion됨을 확인할 수 있었다. 그리고 Major GC는 객체들이 계속 Promotion되어 Old 영역의 메모리가 부족해지면 발생하게 된다. Young 영역은 일반적으로 Old 영역보다 크키가 작기 때문에 GC가 보통 0.5초에서 1초 사이에 끝난다. 그렇기 때문에 Minor GC는 애플리케이션에 크게 영향을 주지 않는다. 하지만 Old 영역은 Young 영역보다 크며 Young 영역을 참조할 수도 있다. 그렇기 때문에 Major GC는 일반적으로 Minor GC보다 시간이 오래걸리며, 10배 이상의 시간을 사용한다.
  • 아래의 Sun JVM의 Heap 영역의 메모리 동작 과정을 간단하게 요약하면 아래와 같다.
    1) 최초의 객체는 Young Generations의 Eden에서 생성된다.
    2) 이후 Eden이 Full이 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 From Space로 이동한다.
    3) 다시 Eden이 GC가 발생하면 From Space의 객체는 To Space로 이동하게 된다.
    4) 마지막으로 이 과정이 반복되면서 객체가 여전히 살아있는 상태라면 Old Generationd 영역으로 이동하게 된다.





마치며 ...

  • 확실히 깊게 들어가니 매우 흥미롭고 어려운 부분이 있다.
  • GC 알고리즘도 있다고 하니 학습을 기회되면 해볼 예정이다.

참고

profile
이게 되네?
post-custom-banner

0개의 댓글