SUMMARY/JAVA

[JVM 밑바닥까지 파헤치기] 2장 자바 메모리 영역과 오버플로우

grammiboii 2025. 8. 15. 17:51

 

자바 스레드, 동시성 강의와 책을 병행하려고 한다.

 

런타임 데이터 영역

https://gothax.tistory.com/48

강의에서 본 자바 메모리 영역을 이렇게 봤었다.

책을 읽어보니 조금 더 자세하게 나와있었다.

 

 

 

 

프로그램 카운터 (Program Counter Registry)

이부분이 위 그림에 안나와 있었다 편의상 생략된듯

 

pc register는 작은 메모리 영역으로

현재 실행중인 스레드의 바이트코드 줄 번호 표시기라고 할 수 있다.

 

스택 영역에서 메서드를 실행할때마다 스택 프레임을 쌓고, 코드를 한줄한줄 실행한다고 했던거 기억이 나는가?

여기서 그 한줄한줄 실행할때 어디인지를 기록하는 것

 

좀더 이론적으로

바이트코드 인터프리터가 이 카운터의 값을 바꿔 다음 실행할 명령어를 선택하는 식으로 작동한다.

이를 이용해 프로그램의 제어 흐름, 분기, 순환, 점프 등을 표현한다.

예외처리, 스레드 복원같은 기본 기능이 이 표시기를 사용한다.

 

당연히 스레드별로 분리되어 있다. (스레드 프라이빗 메모리)

 

유일하게 OOM out of memory 예외 조건이 명시되지 않은 영역이라고 한다.

 

스택 영역 (Stack)

복습할겸 다시 적어보면

 

스레드 별 하나의 실행 스택이 생성되고 (스레드 수 만큼 스택이 생성된다)

 

자바 메서드를 실행하는 스레드의 메모리 모델을 설명해준다.

각 메서드가 호출될 때마다 가상머신이

스택 프레임을 생성해 지역변수 테이블, 피연산자 스택, 동적 링크, 메서드 반환값등의 정보를 저장한다.

 

그리고 이 스택프레임을 스택 영역에 push, pop을 반복

 

 

지역 변수 테이블에는 컴파일 타임에 알 수 있는

데이터 타입, 객체 참조, 반환 주소 타입을 저장한다.

 

이 값들을 저장하는 공간들을 지역 변수 슬롯이라고 한다. (일반적으로 32bit)

이는 컴파일 과정에서 할당되고 메서드 실행중에 절대 변하지 않는다. (슬롯 개수)

 

<<자바 가상 머신 명세>>에서

스택 메모리 영역에서는 두가지 예외를 던질 수 있도록 정의했다

1. StackOverFlow

    요청한 스택 깊이가 가상머신이 허용하는 깊이보다 깊을때

2. OOM

    현재의 핫스팟 가상 머신은 스택 용량을 동적으로 늘리지 못하기 때문에 던질 일이 없다고 한다

    이거 뭔말인지 모르겠다

 

 

마찬가지로 스레드별로 분리되어 있다. (스레드 프라이빗 메모리)

 

힙 영역 (Heap)

 

객체 인스턴스를 저장한다.

모든 인스턴스와 배열을 생성하는데 

책에는 "거의" 모든이라고 나와 있다. 구현 관점에서 자바가 발전하며 스택 할당과 스칼라 치환 최적화 방식이 살짝 달라져서라고 하는데, 뭔말인지 잘 모르겠다. 일단 모든 인스턴스라고 이해하고 넘어가자.

 

 

GC가 관리하는 메모리 영역이어서 GC 힙이라고도 부른다.

객체 할당 효율을 높이고자 스레드 로컬 할당 버퍼 여러개로 나뉜다고 한다. 즉 메모리 회수와 할당을 더 빠르게 하기 위함이라고 하는데 이건 뒤에 나오는 것 같다.

 

자바 힙은 크기를 고정할수도, 확장할수도 있게 구현할 수 있다. 주류로 사용되는 가상 머신은 대부분 확장 가능한 형태라고 한다.

 

이로 인해 새로운 인스턴스를 위한 힙 영역이 부족하고, 힙을 확장할 수 없을때

OOM 예외를 던진다.

 

인스턴스를 참조해야하니까 힙 영역은

모든 스레드가 공유한다.

 

 

메서드 영역 (Method)

 

가상 머신이 읽은

타입정보, 상수, static 변수, 코드 캐시등을 저장한다.

 

다른 강의에서 봤던 그림에는

클래스 정보, static 변수, 상수풀을 저장한다고 되어 있는데

 

타입 정보 + 코드 캐시 -> 클래스 정보

static 변수

상수

이렇게 생각하면 될 것 같다.

 

코드 캐시를 좀더 자세하게

JIT 컴파일러가 컴파일한 코드라고 이해하면 된다고 한다.

 

 

 

힙과 마찬가지로

모든 스레드가 공유한다.