본문 바로가기
책벌레와 벌레 그 사이 어딘가/개념쌓기

[개념쌓기] 가비지컬렉터? JVM에서 힙?

by veganwithbacon 2023. 1. 9.
반응형

https://veganwithbacon.tistory.com/158

 

[개념쌓기] 메모리? 스택,힙?

메모리가 무엇을 하는지 알아보고 JAVA 내에서의 메소드 영역의 역할 및 가비지컬렉터의 기능까지 같이 공부할 계획이다. 우선 메모리가 어떻게 이뤄져있는지를 알아보자. 🔔성격 급한 꼬레아

veganwithbacon.tistory.com

이제 메모리가 무엇인지 힙과 스택의 차이는 알았으니 Java 메모리에서 메소드 영역이 무엇을 하는지 알아보자

 

 

보자보자 어디보자 넌두고보자

가비지 컬렉터는 지금보자

 

  🔔GarbageCollector

더 이상 필요없어진 메모리를 쓰레기(Garbage),

쓰레기를 효과적으로 처리하는 작업을 Garbage Collection(GC)라고 부른다

메모리 관리 방법 중에 하나로, 시스템 상에서 더이상 사용하지 않는 동적 할당된 메모리 블럭을 찾아 자동으로 다시 사용한 자원으로 회수한다. 시스템에서 가비지컬렉션을 수행하는 부분을 GarbageCollector라 부른다. 

 

C언어는 메모리를 할당한 뒤 free()를 통해 수동으로 직접 해제까지 해줘야 한다.

그러나 Java나 Kotlin을 이용해 개발을 하다보면 개발자가 메모리를 직접 해제해주는 일이 없는데 그 이유는

JVM의 가비지 컬렉터가 불필요한 메모리를 알아서 정리해주기 때문이다. 

가비지 컬렉션 기능을 채택한 언어의 경우, 가비지 컬렉션에서  제공하는 할당/해제를 통해 자동으로 프로그램이 실행되며 생기는 쓸모없어지는 메모리들을 알아서 수집하고 관리해준다.

 

JVM에서 가비지 컬렉터를 자동으로 메모리를 관리해준다 해서  내부 구조나 동작원리를 공부할 필요가 없는 것은 아니다.

Springboot에서 자동적으로 처리를 해준다한들, 우리가 Springboot의 내부 동작요소에 대해서 공부하는 것처럼 말이다.

 

✔메모리 누수(Memory Leak)?

메모리의 힙(Heap)영역에 할당된 부분이 참조되지 않는데도 해제되지 않고 메모리를 계속 점유하고 있는 상태

 

  • 같은 기능의 프로그램이어도 메모리 관리에 의해 속도나 프로세스 실행 시간 등의 이유로 성능이 좌우된다
  • 결국 자동이기에 한계가 존재하여 메모리를 효율적으로 사용할 수 있는 코드를 작성하는 것은 개발자의 몫

메모리 누수에 대해 알았으니 쓰레기(Garbage), 즉 사용되지 않는 객체가 무엇인지 알아보자.

힙 영역에는 Reachable, Unreachable의 상태로 구분되는데, 오라클 공식 문서에서는 객체의 참조 유형을 구분하여 사용유무를 'Reachability'로 표현한다.

 

힙 영역 내에서 객체에 대한 참조는 다음 4가지 종류이다

  • 힙 영역 내의 다른 객체에 의한 참조
  • 스택 영역의 Java 메소드 내에서 실행하는 지역 변수, 파라미터, 연산 중 피연산자에 의한 참조
  • 메소드 영역의 상수 풀이나 정적 변수에 의한 참조
  • 메모리에 남은 Native 메소드로 넘겨진 객체에서 참조(JNI에 의해 생성된 객체에 대한 참조)

 

Bold처리를 한 3가지가 Root set(시작점 세트)로 Reachability의 판명 기준이 된다. Root Set으로부터 어떤 식으로든 참조 관계가 있다면 Reachable Object, 없다면 Unreachable Object라 판단한다.

https://d2.naver.com/helloworld/329631

위 그림에서 확인할 수 있듯이 Unreachable Objects로 판명되면 가비지 컬렉터가 해당 객체를 처리한다.

i`m feeling untouchable,untouchable~ (meghan trainor - NO)

 


  GC 작업을 하는 가비지 컬렉터가 하는 일

 - 메모리 할당

 - 사용 중인 메모리 인식

 - 유효하지 않은 메모리 인식

 

프로그램 실행 시 메모리를 관리하는 OS에 프로그램 실행에 필요한 메모리를 요청

-> 메모리를 어디에 저장할지 offset주소를 할당

위 과정에서 할당된 메모리들은 프로그램이 돌아가면 'Garbage'가 발생한다.

기존의 메모리를 새롭게 선언되거나 형변환이 되면서 주소를 잃거나 찾을 수 없게 되어 정리되지 않은 메모리가 발생한다.

 

자바에서 JVM(Java Virtual Machine)은 메모리를 할당받고 프로그램 실행 중 메모리가 부족해지면 추가로 메모리를 요청한다. 이때 가비지 컬렉터가 실행된다. 가비지 컬렉터는 JVM 메모리 중 Heap 영역에서 사용하지 않는 객체를 삭제해준다.

 

가비지 컬렉터는 내부적으로 finalize() 메서드를 호출해 객체를 메모리에서 해제시킨다.

 

당연하게 가비지 컬렉터는 JAVA에서만 작동하는 것이 아니다. 개발자가 힙을 사용할 수 있는 만큼 자유롭게 사용이 가능하고, 더 이상 사용되지 않는 객체들은 가비지 컬렉션을 담당하는 프로세스가 자동으로 메모리에서 제거하도록 하는 것이 가비지 컬렉션의 기본 개념이다.

 

  JVM의 메모리 영역

 위 이미지에서 알 수 있듯이 JVM의 메모리 영역에서는 Method Area, Heap, Java stacks, pc registers, native method stacks 총 5개의 runtime data areas로 구성되어있다.

 

그리고 5개의 영역 중에서 Heap메모리의 특징은 다음과 같다

1. new 연산자를 통한 동적으로 생성되는 객체가 저장되는 공간(or 배열)

2. Heap에 저장된 데이터는 메모리 관리가 필요한 GC 대상

    - 사용되지 않는 메모리라면 GC에 의해 제거된다

3. 모든 쓰레드(Thread)가 공유하는 공간

4. JVM 실행시 생성된다


처음 설계시 JVM의 Heap영역은 2가지의 전제로 설계된다

1. 대부분의 객체는 금방 접근 불가의 상태가 된다

2. 오래된 객체에서 새로운 객체로의 참조는 매우 드물다

 

객체는 대부분 일회성이며, 메모리에 오래 머누는 경우는 드물다.

객체의 생존기간에 따라 물리적인 Heap영역이 나뉘었고, Young과 Old가 있다.

기존에 있던 Perm영역은 Java8부터 없어졌다.


🔔JAVA에서의 HEAP 구조

👌본격적으로 정리 전에 알아야할 키워드 2가지

Reachable

- 접근가능한 객체라는 의미로, 사용중이라는 의미

Unreachable

- 접근 불가한 객체라는 의미로, 사용하지 않는다는 의미

 

  Young Generation(Young 영역)

- 새로 생성된 객체가 할당되는 영역

- 위에서 말했듯이 대부분의 객체가 금방 접근불가(Unreachable)상태가 되기 때문에,

   많은 객체가 Young 영역에 생성되었다 사라진다

- Young 영역에 대한 가비지 컬렉션을 Minor GC라 부른다

eden 
- Young 영역 중에서도 특히 막 생성딘 객체들이 위치하는 곳

survivor
- 영역이 두 개 존재하는데 eden에서 생존된 객체들이 당분간 생존해 있는 곳

 

  Old Generation(Old 영역)

-Young 영역에서 Reachable 상태를 유지해 남은 객체가 복사되는 영역

- 특정 횟수 이상을 생존한 reference가 존재하는 곳

- Young 영역보다 크게 할당되며, 영역의 크기가 사용한만큼 가비지는 적게 발생한다

- Old 영역에 대한 가비지 컬렉션을 Major GC(Full GC)라고 부른다

 

  Permanent

- Method Area의 메타정보가 기록된 곳

 


  GarbageCollector의 동작 방식

Young/Old 영역으로 분리되어 있듯이 다른 메모리 구조로 인해 세부적인 동작 방식이 다르다. 

그러나 가비지 컬렉션이 실행된다고 해도 아래 공통적인 두 가지를 실행하게 된다.

1. Stop The World

2. Mark And Sweep

 

1️⃣Stop The World

Stop The World는 가비지 컬렉션을 실행하기 위해 JVM이 애플리케이션의 실행을 멈추는 작업이다.

GC가 실행될 때는 GC를 실행하는 스레드를 제외한 모든 스레드들의 작업이 중단되고, GC의 작업이 완료되면 작업이 재개된다. 모든 스레드들의 작업이 중단되면 애플리케이션이 멈추기에, GC의 성능 개선을 위한 튜닝은 일반적으로 Stop The World의 작업 시간을 줄이는 작업을 말한다.

JVM에서도 위 문제의 해결을 위해 다양한 옵션이 제공된다.

 

2️⃣Mark And Sweep 

- Mark

: 메모리의 사용 유무를 식별하는 작업

 

- Sweep 

: Mark 단계에서 사용되지 않은 것으로 식별된 메모리를 해제하는 작업

 

Stop The World를 통해 모든 작업이 중단되면, GC는 스택의 모든 변수나 Reachable객체를 스캔하며 각각 어떤 객체를 참조하고 있는지를 탐색하게 된다. 또한 사용되고 있는 메모리를 식별하는데, 이런 과정을 Mark라고 한다.

이후 Mark 되지 않은 객체들을 메모리에서 제거하는 작업Sweep이라고 한다.

https://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java

🔔Minor GC의 동작 방식

Young 영역은 1개의 Eden영역과 2개의 Survivor 영역 총 3가지로 나뉜다.

객체가 새롭게 생성되면 Young 영역 중 Eden영역에 할당된다.

이후 Eden 영역이 가득차게 되면 Minor GC가 발생하고, (사용중인) Eden영역에서의 객체는 Survivor영역으로 옮겨지게 된다.(위 그림에서 표시된 부분은 S0,S1부분)

Survivor 영역은 2개이나 오직 1개에만 데이터가 존재해야한다.

 

👌Young 영역의 동작 순서

1. 새로 생성된 객체가 Eden 영역에 할당

2. 객체가 지속적으로 생성되어 Eden 영역이 가득 차게 되어 Minor GC가 실행된다.

    - Eden 영역에 사용되지 않는 객체의 메모리가 해제

    - Eden 영역에서 남아있는 객체는 1개의 Survivor 영역으로 이동된다

3. 1~2번 과정이 반복된 후, Survivor 영역이 가득차게 되면 Survivor 영역의 살아남은 객체를 다른 Survivor영역으로 이동시킨다.(1개의 Survivor 영역은 빈 상태가 된다)

4. 위 과정들이 반복하여 생존한 객체는 Old영역으로 이동된다

 

 

객체의 생존 횟수를 카운트하기 위해 Minor GC에서 객체가 살아남은 횟수를 의미하는 age를 Object Header에 기록한다.

그 후 Minor GC 때 Object Header에 기록된 age를 통해 이동 여부를 결정한다.

무조건 Survivor 영역 중 1개만 사용이 되어야하는 것과는 별개로 1개는 무조건 사용이 되어야한다.

두 Survivor 영역에 데이터가 모두 존재하거나, 양쪽 모두 존재하지 않는다면 정상적이지 않은 상황임을 파악할 수 있다.

 

 

🔔Major GC의 동작 방식

Young 영역에 오래 남은 객체는 Old영역으로 이동한다는 것을 알 수 있었다. 

Major GC는 객체들이 지속적인 이동을 통해 Old영역의 메모리가 부족해지면 발생된다.

Minor GC의 시간이 무시가 가능할 정도로 짧기에 Stop The World가 이뤄지지 않는다고 간주하고는 한다.

일반적으로 Young 영역은 Old영역보다 크기가 작아 보통 GC가 0.5~1초 사이에 끝난다.

그렇기에 Minor GC는 애플리케이션에 크게 영향을 주지 않는다. 그러나 Old 영역은 Young 영역보다 크며 Young영역을 참조할 수 있다. 

위와 같은 이유 때문에, Major GC는 일반적으로 Minor GC보다 시간이 오래 걸리며, 10배 이상의 시간을 사용한다.

 

Minor GC Major GC
대상 Young Generation Old Generation
실행 시점 Eden 영역이 꽉 찬 경우 Old 영역이 꽉 찬 경우
실행 속도 빠름 느림

 

참고 자료 : 

https://blog.metafor.kr/163 

https://mangkyu.tistory.com/118 

https://tecoble.techcourse.co.kr/post/2021-08-30-jvm-gc/ 

https://sseambong.tistory.com/291

https://beststar-1.tistory.com/15

https://hajoung56.tistory.com/43

https://choisee02.tistory.com/57https://choisee02.tistory.com/57

반응형

댓글