JVM 구성
아래 3가지만 기억
- Class Loader(로더): 실행을 위한 Bytecode(.class)를 가져온다.
- Runtime Data Area(메모리): 바이트 코드를 메모리에 얹고
- Execution Engine(엔진): 구동한다.(바이트코드 -> 기계어)
1. Class Loader
javac(컴파일러)를 통해 컴파일된 바이트코드는 Class Loader가 아래 Runtime Data Area에 적재
컴파일 후 생성되는 바이트코드가 엄청 많은데 이걸 메모리에 한번에 올려서 구동하면 메모리 과부화... 그래서 class Loader가 필요한 클래스만 꺼내서 메모리에 올려준다.
- 동적 로딩(Dynamic Loading): 필요한 바이트코드만을 Runtime Data Area(메모리)에 적재
- 3가지 절차를 수행: Loading -> Linking -> Initailzation
Runtime Data Area (JVM메모리)
✅ Thread영역
스레드 실행단위는 메서드
스레드는 아래 3가지 영역으로 나뉜다
- Stack
- PC Refister
- Native Method Stack
⭐️1. Stack 영역: 지역변수, 파라미터, 리턴값
메서드가 호출될 때마다 메소드 콜스택이 스택 프레임이라는 스택메모리에 쌓이게 되고,
메서드 수행이 끝나면 프레임 별로 삭제한다.
- 기본(primitive)타입 변수는 Stack영역에 직접 값을 가진다.
- 참조(reference)타입 변수는 Heap영역이나 Method 영역에 객체 주소를 가진다.
2. PC Register
스레드 생성될때마다 생성되는 영역, 스레드 실행 부분의 주소와 명령 저장
- 심화: Program Counter: CPU의 Register-Base가 아닌 Stack-base로 동작
3. Native Method Stack
자바 이외의 언어 수행을 위한 개별 스택
- 심화: JNI(Java Native Interface)를 통해 호출되는 C/C++ 등의 코드를 수행하기 위한 스택이다.
- 네이티브 메소드의 매개변수, 지역변수 등을 바이트 코드를 저장한다.
JNI란?
JVM위에서 실행되고 있는 자바 코드가 네이티브 응용 프로그램(하드웨어나 운영체게 플랫폼에 종속된 프로그램들) 그리고 C, C++ 그리고 어셈블리 같은 다른 언어들로 작성된 라이브러리들을 호출하거나 반대로 호출되는 것을 가능하게 하는 프로그래밍 프레임워크이다.
✅ Thread 공유영역
모든 Tread가 공유하는 영역으로 두가지가 있다.
- Method / Static 영역
- Heap 영역
1. Method / Static 영역
전역변수, Static 변수, Final Class, Class의 필드와 메서드 정보 등을 담고 있다.
- 프로그램 시작부터 끝까지 메모리에 상주한다.
2. Heap 영역
객체(인스턴스, 배열) 저장 <- Garbage Collection의 대상
동적 메모리인 애들이 저장된다.
Garbage Collection (GC)
https://blog.naver.com/kbh3983/220967456151
프로그램을 실행한다는 것 = 메모리에 필요한 함수나 객체를 올려수 실행한다는 것 = 사용하지 않는 객체나 함수를 치워야한다
프로그래밍을 하다가 out of Memory를 본적이 있을 것이다. 이게 의미하는 바가 무엇인가?
-> 힙이 터진것, 너무 많은 객체를 만들거나 객체를 치우지 않아서 발생한다.
Java언어에서는 JVM이 대신 프로그램이 생성한 객체를 자체 알고리즘으로 알아서 치워준다.
- 심화: Minor GC / Major GC 모두 Stop-The-World Event (다른 스레드 모두 멈춤)
- 왜? Heap은 모든 Thread들이 공유하는 영역이니까 heap을 치우려면 다른 Thread들이 사용하지 못하게 메모리 잠깐 잠구고 치워야지
- 어떤 가비지 컬렉터 알고리즘을 사용하더라도 stop-the-world는 발생한다.
- 대개의 경우 가비지 컬렉터 튜닝이란 stop-the-world 시간을 줄이는 것이다.
Young / Old Generation
가비지 컬렉터를 효율적으로 동작시키기 위해 Heap영역을 크게 2개 물리적 공간으로 나누었다.
1. Young/New Generation
대부분 객체는 오랜시간동안 살아있지 않는다 -> young 에서 웨만하면 다 이탈
Minor GC 대상
사용되지 않은 객체 제거 및 이관 (높은 주기, 짧은 시간)
young Generation에서 다시 3가지로 나뉜다.
- Eden
- Survivor 0
- Survivor 1
2. Old/Tenured Generation
오래된 객체에서 젊은 객체로의 참조는 아주 적게 존재한다. -> old에 잘 안남겨진다.
Major(full) GC 대상
사용되지 않은 객체 제거 (낮은 주기, 긴 시간)
GC 설정을 통한 튜닝
Heap 사이즈의 설정에 따라 GC에 소요되는 시간등을 세부 조율할 수 있다.
메모리를 적게 쓰는것이 목표인지, GC 횟수를 줄이는 것이 목표인지, GC에 소요되는 시간이 목표인지, Application 의 성능(Throughput or response time) 향상인지를 먼저 정의한 후에 그 목표치에 근접하도록 JVM Parameter를 조정하는 것이 필요하다.
Runtime Data Area(JVM메모리) 영역에 따른 3가지 Java 변수 분류
1. 정적(클래스) 변수 (static variable)
- 클래스 내 필드/메서드와 정적 필드/메서드 -> Method/Static 영역
2. 인스턴스(객체) 변수 (Instance Variable)
- new 키워드로 인스턴스 생성 시 생성자로 적재 -> Heap 영역
3. 지역변수 (Local Variable)
- 메서드 호출 시 필요한 파라미터나 내부 변수 -> Stack영역
3. Execution Engine 의 역할
1. Runtime Data Area에 적재된걸 실행
- 인터프리터: Bytecode -> binarycode(기계어)로 변환하여 실행
- JIT 컴파일러: 실행이 잦은 Bytecode -> 기계에러 미리 컴파일해 놓는것
2. Runtime Data Area에 적재될걸 정리 : Garbage Collection
'ASAC 웹 풀스택' 카테고리의 다른 글
[Git] 파일 수정 시나리오: 하나의 파일에 기능이 여러개 추가된 경우 (0) | 2024.10.28 |
---|---|
Java 기본 문법 및 JVM 구성(3) - ⭐️Exception 예외 처리 (3) | 2024.09.27 |
Java 기본 문법 및 JVM 구성(2) - 자바 개발 환경 설정(Intellij, Gradle, Lombok) (2) | 2024.09.25 |
Java 기본 문법 및 JVM 구성(1) - Java동작 원리 (0) | 2024.09.25 |
React 의 특장점, 렌더 라이프사이클 및 Hook(7) - immer(리렌더링 이슈 해결) (1) | 2024.09.22 |