HotSpot 객체의 메모리 할당

블러거·2025년 12월 24일

JVM

목록 보기
3/26
post-thumbnail

HotSpot 기준으로 객체가 메모리에서 어떻게, 어떤 형태로 생성되며 어떻게 참조될까.

객체 생성

객체를 생성하려면 클래스 로딩이 안되어 있으면 로딩 후에
메모리를 할당하고, 메모리 공간을 0으로 초기화한 뒤, 객체 해더값을 채우고, 생성자를 실행한다.

이 모든 과정은 new 라는 자바 키워드를 실행하며 이뤄진다.

메모리 할당

자바 new 키워드는 new + invokeSpecial 바이트코드 명령으로 컴파일된다. 이 new 바이트코드 명령어를 만나면 객체를 위한 메모리를 할당한다.

객체 생성에 필요한 메모리의 크기는 클래스로딩 시점에 정해진다.

메모리에서 객체를 할당할 공간을 확보하기 위해 두가지를 고려해야 한다.
1. 새로운 객체를 할당할 메모리의 빈공간 관리
2. 멀티 스레드 환경에서 메모리의 빈공간 이라는 공유 자원을 스레드 안전 하게 차지하는 방법

빈 공간 관리

빈 공간 관리에는 두가지 방법이 있다.
1. bump the pointer
2. free list

Bump The Pointer (포인터 밀치기)


자바 힙에서 이미 객체가 할당되어 사용중인 메모리의 끝을 가리키는 포인터가 있다고 가정하면, 거기서부터 새로운 객체를 위한 메모리를 할당 후 포인터를 밀치는 방식이다.

Free List (여유 목록 관리)

객체의 여유 메모리 목록을 따로 관리하는 방식이다.

어떤것을 사용하는가.

사용중인 메모리와 여유 메모리가 Bump The Pointer 의 그림처럼 규칙적으로 칼같이 나눠 있다면, 포인터 하나만으로 여유 공간을 관리할 수 있으므로 효율적이고 빠르다.

하지만 객체마다 수명이 다르기 때문에 GC 후 자바 힙은 빈공간이 규칙적으로 사용중 메모리와 여유 메모리로 나뉘지 않는다.

따라서 이 기준에는 Garbage Collector 의 GC 방식에 따라 좌우되는데,
Compact(GC 후 사용중인 공간 모으기) 방식 GC 라면 Bump The Pointer 를 사용하고
Sweep 방식 GC 라면 Free List 방식을 사용한다.

실제로는 Sweep 방식을 사용하는 CMS 는 실제로 여유 목록에 거대 버퍼(Linear Allocation Buffer) 를 두고 Bump The Pointer 방식을 사용한다. 할당 속도가 더 빠르기 때문에.

스레드 안전한 메모리 할당

멀티 스레드 환경에서는 여러 스레드가 하나의 메모리에 객체를 생성하려 시도한다.
메모리는 공유 자원이다.
이 때 같은 메모리 공간에 대해 여러 스레드가 객체를 생성하려들면 문제가 생길 것이다.

여기에도 두가지 해결책이 있다.
1. 메모리 할당 동기화
2. TLAB

메모리 할당 동기화

메모리를 할당하는 동작 자체를 원자적으로 수행하면 된다.
대표적인 Lock-Free 방식인 CAS 로 수행할 수 있다.

TLAB

Thread Local Allocation Buffer 의 약자이다.
(자바 라이브러리의 ThreadLocal 과 다른놈이다)

이 방식은 각 스레드마다 객체 할당을 위한 전용 메모리를 힙에서 미리 받아놓는 방식이다.
각각의 스레드는 독립된 공간을 할당받기에 동시성 문제를 해결할 수 있다.

-XX:+/-UseTLAB 옵션을 주면 이 방식을 사용할 수 있다.

할당 후 초기화

객체에 대한 메모리가 할당되면 할당받은 공간을 0 으로 초기화 한다.
이 과정에 의해 자바에서는 객체 인스턴스 필드를 따로 초기화하지 않고도 0이라는 초기값을 사용할 수 있는 것이다.

객체 헤더값 설정

객체 헤더값을 채운다.
여기에는 여러 값이 들어가는데 아래에서 다시 설명.

생성자 실행

정확하게는 invokespecial 바이트코드 명령어를 실행한다.
이 명령어는 컴파일러가 만들어낸 클래스의 <init>() 메서드를 실행하여 유저가 정의한 생성자를 호출한다.

인터프리터 코드 보기

여기를 보면 인터프리터에서 new 바이트코드 명령어때 실행되는 코드를 볼 수 있다.

실제 우리가 구동하는 jvm 은 이대로가 아닌 다양한 최적화가 구현된 코드겠지만, 기본 개념을 눈으로 확인할 수 있어 좋다.

const pool 조회, TLAB 할당등을 볼 수 있다.

profile
안녕하세요!

0개의 댓글