티스토리 뷰
stack 영역은 지역변수나 함수와 같이 일시적으로 사용되는 데이터들이 저장되며, 함수 호출이 종료되면 해당 데이터는 사라진다. 반면, heap 영역은 new 연산자로 생성된 객체들이 할당되며 이 객체들은 메모리 관리법에 따라 해제된다. 이 메모리 관리법은 GC(Garbage Collection)이라고 하며, GC의 동작원리에 대해 알아보려고 한다.
GC (Garbage Collection)
메모리 관리 기법 중 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요 없게 된 영역을 해제하는 기법이다.
프로그램에서 사용중이거나 참조되고 있는 객체는 여전히 포인터를 유지되고 있지만, 참조되지 않는 객체는 더 이상 프로그램에서 참조되고 있지 않는다. 따라서 더이상 참조되지 않는 객체에 대한 메모리를 회수할 수 있다. 자바에서는 이러한 메모리 회수 작업을 Garbage Collector 가 자동으로 처리해준다.
Garbage Collection 동작
일반적인 Garbage Collection 방법으로 Full GC라고도 한다.
Step 1. Marking

어플리케이션의 모든 객체를 스캔하고 사용중인 메모리와 미사용중인 메모리에 대해 마킹하는 단계이다. 참조가 되고 있는 객체는 파란색으로, 참조가 되고있지 않은 객체는 주황색이다. 모든 객체를 검사해야 하기 때문에 매우 많은 시간이 걸리는 단계이다.
Step 2. Normal Deletion

참조되고 있지 않은 객체를 제거하고 참조되는 객체와 포인터를 여유공간에 남긴다.
메모리 할당자는 새 객체를 할당할 수 있는 여유 공간 블록에 대한 참조를 갖고있는다.
Step 3. Deletion with Compacting

참조되지 않는 객체를 삭제하고, 참조되고 있는 객체에 대한 압축한다. 이 과정을 통해 메모리 단편화(객체들이 흩어져 있어 연속된 공간을 찾기 어려운 상황)를 줄일 수 있다. 이로 인해 메모리 할당이 훨씬 쉽고 빨라진다. 이 과정이 끝난 후 메모리 할당자는 여유 공간의 시작 부분에 대한 참조를 유지하며, 새로운 객체가 생성되면 여유 공간 시작 부분부터 메모리를 할당한다.
Full GC의 단점과 Generation Garbage Collection의 탄생
위에서 Full GC의 동작 과정을 살펴보았다.
Full GC 큰 단점은 모든 객체를 마킹하고 압축하는 과정에 있다. 이는 GC의 시간이 오래 걸리게 되고 어플리케이션의 성능에 큰 영향을 미친다.
그 이유는 SWT(Stop-the-World) 현상 때문이다. GC가 실행되면 GC를 실행하는 스레드를 제외한 어플리케이션의 모든 스레드는 중단된다. 또한, 압축 작업으로 인해 메모리 단편화가 줄어들지만, 압축 자체에 대한 비용이 많이 들고 성능에 영향을 미친다.
그렇지만 어플리케이션에 대한 경험적 분석에 따르면 대부분의 객체의 수명은 짧다.

시간이 지날수록, 할당된 객체의 수는 점점 더 적어진다는 것과, 대부분의 객체는 수명이 매우 짧다는 것 또한 볼 수 있다. 이러한 결과를 통해 JVM에서 메모리 관리 방법은 변경되었으며, 이는 Generational Garbage Collection이라고 한다.
Generational Garbage Collection의 핵심
자바에서는 다음과 같이 Heap 메모리 영역을 세대별로 나누어서 관리한다.

Young Generation
새로운 객체가 할당되는 영역으로 Eden과 Survivor(S0, S1) 영역으로 나뉜다.
Eden 영역은 new를 통해 생성된 객체가 위치하며, minor GC에 의해 살아남은 객체들은 Survivor 영역으로 이동한다.
S0/S1 영역은 최소 1번 이상 살아남은 객체가 존재하는 영역으로, minor GC가 발생할 때마다 둘 중 한 영역은 비어 있어야 한다.
이 영역들이 다 채워지게 되면 minor GC가 발생하며, 이 과정은 객체의 생명 주기가 짧다는 가정 하에 진행된다. minor GC를 통해 소멸된 객체들은 빠르게 정리되고, 살아남은 객체들은 점차 나이가 들어가 일정 조건(객체에 대한 임계값)을 만족하면 Old Generation 영역으로 이동한다.
Old Generation
오래 살아남은 객체를 저장하는 영역이다. Young Generation 영역에서 일정 조건을 만족해서 이동된 객체를 이곳으로 이동한다. Young generation 영역보다 크게 할당되는 만큼 GC는 적게 발생한다. 이 영역에 있는 객체들을 관리하는 GC를 major GC(Full GC)이라고 한다. major GC는 Young Generation보다 많은 객체를 포함하므로 속도가 훨씬 느리다.
Stop the World Event
minor GC 와 major GC 과정에서 발생하는 이벤트로, GC가 발생할때에 GC를 실행하는 스레드를 제외한 어플리케이션의 모든 스레드가 작업을 멈추는 현상이다. GC 작업을 완료된 이후에 중단되었던 스레드들은 작업을 다시 시작한다.
Permanent Generation (java 8 ~ : Metaspace)
JVM이 어플리케이션에 사용되는 클래스와 메서드에 대한 메타데이터를 포함하는 영역이다. 어플리케이션에서 사용 중인 클래스들을 기반으로 런타임 시 JVM에 의해 채워진다. 사용 중인 클래스가 더 이상 필요하지 않고 다른 클래스를 위해 영역이 필요하다고 판단되면 해당 클래스는 GC 대상이 될 수 있으며, 이 영역은 Full GC의 대상이 된다.
Generational Garbage Collection 동작
1. 새로운 객체 생성

새로운 객체를 생성하면 Young Generation의 Eden 영역에 메모리가 할당된다. 이 때, 객체의 나이(Age)는 0이며 Survivor 영역으로 이동할 때에 1이 증가된다.
2. minor GC 의 발생


Eden 영역이 모두 채워지면 minor GC는 발생한다. 참조되고 있는 객체들은 첫 번째 survivor 영역으로 이동하고, 참조되지 않는 객체들은 Eden 영역에서 삭제된다. Survivor 영역으로 이동 된 객체의 나이는 1 증가하여 1이된다.
3. minor GC의 반복


Object Aging 그림은 두 번째 minor GC가 발생하였을 때를 보여준다.
Eden 영역에서 참조되고 있는 객체와 S0 영역에서 살아남은 객체는 S1 영역으로 이동한다. S0 영역에서 살아남은 객체는 S1 공간으로 이동할 때 나이가 1 증가한다.
Eden 영역에서 참조되고 있는 객체가 S1 영역으로 이동하게 된 이유는, GC 과정에서 객체들이 Survivor 영역을 순차적으로 이동하기 때문이다. 즉 첫 번째 minor GC에서 S0 영역으로 이동해서 두 번째인 지금 S1 영역으로 이동한 것이다.
Additional Aging 그림은 세 번째 minor GC가 발생하였을 때를 보여준다.
Eden 영역에서 참조되고 있는 객체와 S1 영역에서 살아남은 객체는 S0 영역으로 이동한다. S1 영역에서 살아남은 객체는 S0 공간으로 이동할 때 나이가 1 증가한다.
이처럼, minor GC가 진행될 때마다 Survivor 영역에 있는 객체들의 나이는 달라지게 된다.
4. 세대 이동


minor GC 이후 객체가 특정 연령 임계값에 도달하면, Young Generation 에서 Old Generation 으로 이동하게 된다. 이를 promotion 이라고 부른다.
이 과정을 통해 Old Generation 영역이 가득차게 된다면, Major GC가 발생한다.
GC의 동작 과정을 요약해보자면 다음과 같은 그림이 된다.

정리
Young Generation : 짧은 생명주기를 가진 객체들이 할당되는 영역으로, Minor GC의 대상이다.
Old Generation : 긴 생명주기를 가진 객체들이 할당되는 영역으로, Major GC의 대상이다.
Minor GC : Young Generation 영역을 대상으로, 실행 속도가 빠르다.
Major GC : Old Generation 영역을 대상으로, Old Generation 영역이 꽉 찬 경우 실행하며 실행 속도가 느리다.
참고
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
Java Garbage Collection Basics
Java Overview Java is a programming language and computing platform first released by Sun Microsystems in 1995. It is the underlying technology that powers Java programs including utilities, games, and business applications. Java runs on more than 850 mill
www.oracle.com
'Language > Java' 카테고리의 다른 글
Lambda와 Stream에 대하여 (0) | 2024.11.14 |
---|---|
HashMap : 해시 충돌이 발생하였을 때 (0) | 2024.11.11 |
컬렉션 이터레이터의 Fail-safe 와 Fail-fast (0) | 2024.11.10 |
Hash 기반 자료구조 (1) | 2024.11.09 |
Hash에 대해서 (0) | 2024.11.08 |
- Total
- Today
- Yesterday
- 인터페이스
- HashMap
- 로드 밸런서
- 정적변수
- Security
- fail-fast
- nginx
- 인스턴스변수
- syncronized
- AutoConfiguration
- Load Balancer
- Spring
- Hash
- nosql
- 고정 세션
- 자동구성
- 추상클래스
- 티스토리챌린지
- 다중화
- HashSet
- fail-safe
- JPA
- @conditional
- Red-Black Tree
- java
- Caching
- 오블완
- object
- spring boot
- Sticky Session
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |