본문 바로가기
Study/JSCODE - 자바

5주차 스터디 노트

by Dev Lighthouse 2024. 9. 12.
320x100
320x100

JVM & GC

 

 


Answer

이번 주 차시는 2년 전인 2022년 8월 과거의 내가 작성했던 글, 저번달에 작성한 글과 관련이 있다

https://code-boki.tistory.com/80

 

Compile, Link, Build, Run (feat. C vs JAVA)

프로그램을 작성하다보면 컴파일 타임, 런타임이란 용어들을 접하고... 컴파일, 런타임을 검색하다보면 링크, 빌드, 바인드 이런 용어들도 접하게 된다 그럼 이제부터 과연 이게 무엇인지에 대

code-boki.tistory.com

https://code-boki.tistory.com/208

 

Mutable/Immutable Object의 Value를 계속 변경하면 무슨 일이 발생할까? (feat. VisualVM, GC)

이번 포스팅으로 Immutable 객체의 상태(값)을 반복해서 변경하면 무슨 일이 발생하는지 알아보자 관찰점: 힙 메모리가 어떻게 변하는지, 힙 메모리에 올라온 객체를 재사용하는지, GC가 몇 번 발

code-boki.tistory.com

 

  • JVM 구조에 대해서 설명해 주세요.

JVM은 크게 4개의 영역으로 나뉘는 구조를 갖고 있다

 

- 클래스 로더 (Class Loader)

- 실행 엔진 (Execution Engine)

- 런타임 데이터 영역 (Runtime Data Areas) [ 그림에서 JVM memory부분 ]

- 네이티브 메서드 인터페이스 (Native Method Interface)

 

 

JVM 구조

 

 

 

  • 클래스 로더에 대해 설명해 주세요.

클래스 로더는 JVM이 Java 프로그램에서 사용되는 클래스 파일을 찾아 로드하는 역할을 한다

 

종류: 클래스 로더는 기본적으로 3가지 종류로 나뉨

부트스트랩 클래스 로더 (Bootstrap Class Loader): 가장 기본적인 클래스를 로드(ex: rt.jar)

- 확장 클래스 로더 (Extension Class Loader): 표준 핵심 Java 클래스의 확장을 로드(ex: jre/lib/ext)

- 애플리케이션 클래스 로더 (Application Class Loader): 클래스패스에 지정된 애플리케이션 레벨의 클래스를 로드(ex: classpath)

 

모델: 클래스 로더는 Parent Delegation Model을 따른다

=> 어떤 클래스가 로드되기 전에 먼저 부모 클래스 로더에게 해당 클래스를 로드할 수 있는지 확인

=> 동일한 클래스가 여러번 로드되는 문제를 방지

위임과정: Application ClassLoader -> Extension ClassLoader -> Bootstrap ClassLoader

위임가능한지 확인이 안되면 역순으로 탐색

 

클래스 로더의 로딩 과정

1. Loading(로딩): 클래스 파일을 찾아 메모리에 로드

2. Linking(링킹): 검증(Verify), 준비(Prepare), 분석/해결(Resolve) 단계를 거침

3. Initialization(초기화): 클래스 변수를 초기화하고 정적 블록을 실행

 

 

 

  • JVM 메모리 구조를 자세히 설명해 주세요.

JVM 메모리 구조는 크게 다섯 가지 영역으로 나눌 수 있다

 

1. Method Area(메서드 영역)

모든 스레드가 공유하는 영역

클래스 메타데이터, 메서드 데이터, 정적 변수, 상수, 생성자 코드 등이 저장됨

JVM당 하나만 생성됨

Java8이전: Permanent Generation(PermGen) / Java8이후: Metasapce 영역이라고 정정

Metaspace는 네이티브 메모리를 사용하므로, PermGen과 달리 자동으로 크기가 조절됨

 

2. Heap(힙 영역)

모든 스레드가 공유하는 영역

객체와 배열이 저장됨

가비지 컬렉션의 대상이 되는 영역

내부적으로 (Young / Old) Generation 영역이 존재

(Young Generation: 새로 생성된 객체가 저장되고, Old Generation: 오랫동안 살아남은 객체가 저장됨)

Generation을 Gen이라고 보통 줄여서 표현하며, Young Gen은 세부적으로 Eden과 두 개의 Survivor 공간으로 나뉨

 

3. Stack(스택 영역)

각 스레드마다 별도의 공간을 가짐(스레드 1개당 1개)

메서드 호출 시마다 프레임이 추가되고, 메서드가 종료되면 프레임이 제거됨

각 프레임은 지역 변수, 매개변수, 중산 연산 결과, 리턴 값 등을 저장

이 영역에서 java.lang.StackOverflowError 에러가 발생


4. PC Register (PC 레지스터)

각 스레드마다 별도의 공간을 가짐(스레드 1개당 1개)

현재 실행 중인 명령의 주소를 저장(JVM 명령의 주소를 가리키는 포인터 역할)

 

5. 네이티브 메서드 스택 (Native Method Stack)

각 스레드마다 별도의 공간을 가짐(스레드 1개당 1개)

JNI(Java Native Interface)를 통해 호출되는 C/C++ 등의 네이티브 코드를 위한 스택

 

 

 

  • 왜 Heap 영역은 Young Generation과 Old Generation으로 나뉘나요?

객체의 수명에 따라 효율적인 메모리 관리를 위해 분할

Young Generation에서 단명 객체를 빠르게 처리하고, Old Generation에서 장수 객체를 관리

 

 

 

  • GC란 무엇인가요?

자동으로 사용하지 않는 메모리를 회수하는 JVM의 메커니즘

개발자가 명시적으로 메모리를 해제할 필요 없이 JVM이 자동으로 처리

이 GC로 인해 자바는 Managed Language(관리형 언어)라고 불림

 

 

 

  • GC의 장단점을 설명해 주세요.

- 장점

메모리 관리 자동화로 개발 생산성 향상

메모리 누수 방지

 

- 단점

GC 작동 시 애플리케이션 일시 정지

성능 오버헤드 발생 가능성

 

 

 

  • GC에서 사용하는 알고리즘은 무엇이 있고, Java는 어떤 알고리즘을 사용하나요?

< 대분류 >

- 참조 횟수 카운팅 GC (Reference Counting Garbage Collection): PHP, Swift

- 추적 기반 GC (Tracing Garbage Collection): Java, Kotlin, Python

 

< 추적 기반 GC >

- Mark-Sweep Algorithm

- Mark-Sweep-Compact Algorithm

- Tri-color Marking Algorithm (Incremental GC)

- Copying Algorithm (Incremental GC)

- Generational Algorithm (Incremental GC)

 

 

  • Java 8 기준으로, GC는 어떤 방식으로 수행되나요?

Java 8의 GC방식은 Parallel GC 또는 Throughput GC라고 불리며 다수의 스레드(멀티 스레드)를 이용해서 GC의 속도가 향상됨

Young Generation에서 Minor GC가 수행되고 Old Generation에서 Major GC가 수행됨

Young Gen에서 동작하는 GC는 PS Scavenge

Old Gen에서 동작하는 GC는 PS MarkSweep

 

 

  • GC의 종류 또는 발전 과정을 아시는대로 말씀해주세요.

1. Serial GC

하나의 스레드로 GC를 실행하는 방식이며 STW(Stop-The-World) 시간이 길고, 메모리 파편화를 막기 위해 Compaction(메모리 압축)을 수행

 

2. Parallel/Throughput GC

여러개의 스레드로 GC를 실행하는 방식이며 STW가 Serial GC보다 상대적으로 짧음. 역시 메모리 파편화를 막기 위해 Compaction을 수행

 

3. CMS(Concurrent-Mark-Sweep) GC

Concurrent. 즉 동시에란 뜻!

가비지 수집 작업을 애플리케이션 스레드와 동시에 수행하기때문에 STW 시간이 감소

하지만 Compaction을 기본적으로 수행하지 않기때문에 시간이 지나면 메모리 파편화가 발생할 수 있음

동시 작업때문에 CPU를 더 많이 소모

자바9에서 deprecated되었으며 자바14에서 제거됨

 

4. G1(Garbage-First) GC

자바9+ 버전의 디폴트 GC

CMS처럼 Heap을 스캔하고 삭제하기 위해 여러개의 Background GC 스레드를 사용

incremental과 concurrent 알고리즘을 사용함과 동시에 긴 멈춤 시간을 방지하고, GC 시간을 예측 가능하고 짧게 유지하는 것이 목표

힙 영역을 동일한 크기의 Region이라 불리는 바둑판과 같은 모양의 논리적인 단위로 쪼개서 이 영역이 가비지로 채워진다면(G1 GC가 런타임에 이 영역을 튜닝), 이 공간을 먼저 회수하는데 집중 => G1이라 불리는 이유

 

5. ZGC

G1과 비슷하게 ZGC는 내부적으로 ZPage라는 영역을 사용하며, G1의 Region은 크기가 고정인데 비해서 ZPage는 가변

Reference Coloring, Relocation, Load Barriers, Remapping, Reclaimed 등의 기법을 사용

대량의 메모리를 낮은 지연으로 잘 처리하기 위해 고안됨

ZGC의 목적 중 하나는 STW 상태를 10ms 아래로 가져가는 것

자바15버전에서 release

 

=> 그럼 왜 성능이 좋은 ZGC를 기본 GC로 하지 않고 G1을 기본 GC로 채택한 것일까?

차이점

1) 용도 - G1: 범용 GC / ZGC: 대규모 힙 GC

2) 자원 사용 - G1: 비교적 효율적으로 사용 / ZGC: 짧은 STW를 유지하기 위해 Load Barriers와 같은 고급기술을 사용하여 CPU 사용량 증가

 

ZGC는 실시간 처리 시스템이나 대규모 메모리를 사용하는 애플리케이션에 유리

모든 애플리케이션이 다 고성능이어야 하는 것은 아님. 그리고 AWS 비용 생각하면......ㅇㅋ?

 

 

  • GC의 실행 방식을 아는만큼 설명해 주세요.

- 동작 순서

1. Heap 영역에 존재하는 객체들에 대해 접근 가능한지 확인

2. GC Root에서부터 시작하여 참조값을 따라가며 접근 가능한 객체들에 대해 Mark

3. Unreachable(접근할 수 없는) 객체는 제거(Sweep) 대상이 되고, 해당 객체들을 제거

 

+ 객체는 Reachable / Unreachable로 구분 가능

Reachable 객체들은 java.lang.ref 패키지를 이용해서 Strongly, Softly, Weakly, Phantomly로 더 자세히 구분되어 각 GC 마다 동작을 다르게 지정할 수 있다

 

GC 발생 영역 구분: Minor GC(Young Generation)와 Major GC(Old Generation)

Minor GC는 자주 발생하며 빠르고, Major GC는 덜 빈번하지만 더 오래 걸림

 

<Young Gen>

새로 생성된 객체: Eden -> S0또는 S1로 이동

Eden 영역이 가득 차면 Minor GC가 발생(Minor GC마다 S0, S1는 역할을 교대하며 생존할 때마다 Age 카운터 증가)

Age가 기본값인 15에 도달하면 Old Gen으로 이동

 

<Old Gen>

Minor GC를 여러번 통과한 객체 또는 장수객체가 존재하는 영역

Old Gen을 Tenured라고도 부름

이 영역이 가득차면 Major GC(Full GC)가 발생

 

default size) Young Gen : Old Gen = 1 : 3

 

단명 객체와 장수 객체의 차이는 객체의 수명(참조되는 기간) 차이

- 단명 객체(Short-lived Object): 메서드 호출 내부의 지역변수(non primitive type), 반복문에서 매번 생성되는 문자열 객체 등

- 장수 객체(Long-lived Object): 애플리케이션 전체에서 사용하는 전역변수, 캐시된 데이터 등

 

 

  • Java 8과 Java 11의 디폴트 GC 실행 방식은 어떤 것인가요?

Java 8: Parallel GC / Java 11: G1 GC

 

코드로도 한번 확인해봤다!^^

Java8 vs Java11
다른 GC

 

  • G1 GC에 대해 설명해 주세요.

G1(Garbage-First) GC

자바9+ 버전의 디폴트 GC

CMS처럼 Heap을 스캔하고 삭제하기 위해 여러개의 Background GC 스레드를 사용

incremental과 concurrent 알고리즘을 사용함과 동시에 긴 멈춤 시간을 방지하고, GC 시간을 예측 가능하고 짧게 유지하는 것이 목표

힙 영역을 동일한 크기의 Region이라 불리는 바둑판과 같은 모양의 논리적인 단위로 쪼개서 이 영역이 가비지로 채워진다면(G1 GC가 런타임에 이 영역을 튜닝), 이 공간을 먼저 회수하는데 집중 => G1이라 불리는 이유

 

 

  • G1 GC의 Heap 구조를 설명해 주세요.

전체 Heap을 동일한 크기의 여러 Region으로 분할

각 Region은 Eden, Survivor, Old, Humongous, Available/Unused로 구성되며 런타임 중 Available or Unused 영역에 동적 할당

(필요에 따라 Available/Unused Region이 메모리 할당 상황에 맞춰 동적으로 변경되는 방식)

Humongous 영역은 Region 크기의 50% 이상인 큰 객체를 저장

 

 

  • 왜 Java 11은 디폴트 GC를 G1 GC로 변경하였을까요?

몇가지 특징과 장점들 때문에 디폴트 GC로 채택한것이 아닐까 싶음

 

1. 낮은 STW Time: G1 GC는 다른 GC 방식에 비해 STW 시간이 짧음

2. 효율적인 메모리 관리: Heap을 고정된 크기의 Region으로 나누어 관리하기때문에 메모리 파편화 문제를 최소화함

3. 우수한 성능: 대용량 메모리(4GB 이상)에서 우수한 성능을 가지며, 예측 가능한 응답 시간을 유지할 수 있음

 

 

 

  • GC를 모니터링해야 하는 이유가 무엇일까요?

애플리케이션의 성능과 안정성을 유지하기 위해 GC 모니터링은 중요

 

불필요한 Full GC가 발생해서 STW가 일어나면 애플리케이션이 긴 시간 멈출 수도 있음

또한 지나치게 잦은 Minor GC가 발생하면 애플리케이션의 응답 시간이 느려질 수도 있음

메모리 누수가 발생하면 GC가 메모리를 해제하지 못하고, OOM(OutOfMemoryError)이 발생할 수 있음

 

 

  • 자바로 jvm 응용 프로그램을 개발한 후에 운영하다보면 out of memory가 나올 수 있는데 이 에러가 발생했을때 어떻게 대처할 것 같으세요?

1. OOM이 발생한 경우 힙덤프 파일을 생성하여 분석

( -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump )

 

2. 실시간 스냅샷 생성, jmap 명령어로 힙덤프 파일 생성

( jmap -dump:format=b,file=testdump.hprof $(jps | grep <현재 실행중인 자바 프로그램 이름> | awk '{print $1}' )

 

OOM이 발생하지 않도록 GC로그 분석, 최대 힙 크기 조정

 

  • 메모리 누수를 어떻게 확인할 것인가요?

VisualVM, JProfiler, YourKit, Eclipse MAT 같은 프로파일링 도구를 사용하여 애플리케이션의 메모리 사용 현황을 실시간으로 모니터링하고, 객체가 계속해서 메모리에 남아있는 경우 메모리 누수를 의심

 

불변객체 사용, 자원반납 확인, 충분한 메모리 확보

 

 

출처

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

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html

 

Chapter 2. The Structure of the Java Virtual Machine

Conditional branch: ifeq, ifne, iflt, ifle, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmple, if_icmpgt if_icmpge, if_acmpeq, if_acmpne.

docs.oracle.com

https://medium.com/java-for-beginners/understanding-java-virtual-machine-jvm-architecture-e68d1c611026

 

Understanding Java Virtual Machine (JVM) Architecture

Most Java developers and students who study software engineering don’t understand what is the importance of learning basic concepts in…

medium.com

https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

 

How JVM Works - JVM Architecture - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC#mark_and_sweep

 

☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리

Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객

inpa.tistory.com

https://woooongs.tistory.com/51

 

JVM Generation 과 GC 과정

JVM Generation JVM 내의 모든 객체를 Mark 하고 Compact 하는 것은 매우 비효율적이기 때문에 Heap 영역은 아래 세가지 영역으로 나뉘어져 있다. Young Generation Old Generation (Tenured Generation) Permanent Generation You

woooongs.tistory.com

https://siahn95.tistory.com/102?category=866017

 

[Algorithm][Garbage Collection] (2) GC 알고리즘 - Reference Counting Algorithm(참조 횟수 카운팅)

지난 1편에 이어, 이번 글부터 본격적으로 Garbage Collection(이하 GC, 가비지 컬렉션)의 알고리즘에 대해 작성한다. 작동 방식에 따라 크게 아래 두 가지로 분류 가능한데, 1. 추적 기반 GC (Tracing Garbage

siahn95.tistory.com

https://siahn95.tistory.com/108?category=866017

 

[Algorithm][Garbage Collection] (3) GC 알고리즘 - Tracing Garbage Collection(추적 기반) : Mark-Sweep, Mark-Sweep-Compact

지난 2편에 이어 Garbage Collection(이하 GC, 가비지 컬렉션)의 알고리즘 중 Tracing GC(추적 기반)에 대해 알아본다. Tracing GC에서는 아래 알고리즘들에 대해 작성할 예정인데, 꽤나 많은 양이 예상되므로

siahn95.tistory.com

https://incheol-jung.gitbook.io/docs/q-and-a/java/heap-dump-feat.-oom

 

heap dump 분석하기 (feat. OOM) | Incheol's TECH BLOG

💡 만약 메모리가 8 GB의 인스턴스에서 아무런 설정 없이 애플리케이션을 운영한다면? 최대 메모리 사이즈 : 8GB / 4 = 2GB 초기 메모리 사이즈 : 8GB / 64 = 127MB

incheol-jung.gitbook.io

 

https://stackoverflow.com/questions/39929758/ps-marksweep-is-which-garbage-collector

 

PS MarkSweep is which garbage collector

My jdk version is : java version "1.8.0_102" Java(TM) SE Runtime Environment (build 1.8.0_102-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode) this is my test code : List<

stackoverflow.com

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

 

 

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

 

https://www.baeldung.com/java-choosing-gc-algorithm

 

 

 

'Study > JSCODE - 자바' 카테고리의 다른 글

JSCODE 스터디 후기(자바 1기)  (10) 2024.09.17
4주차 스터디 노트  (1) 2024.09.05
3주차 스터디 노트  (2) 2024.08.29

댓글