Java 24의 JEP 450: Compact Object Headers로 메모리 효율성 높이기
2025년 3월 릴리즈된 Java 24에서 도입된 가장 주목할 만한 실험적인 기능 중 하나는 JEP 450: Compact Object Headers입니다. 이 실험적 기능은 HotSpot JVM의 객체 헤더 크기를 64비트 아키텍처에서 96
128비트(12
16바이트)에서 64비트(8바이트)로 줄여 힙 크기를 감소시키고 데이터 지역성을 향상시키는 것을 목표로 합니다.
객체 헤더란 무엇인가?
Java에서 힙에 저장된 모든 객체는 메타데이터를 가지고 있으며, 이는 객체의 헤더에 저장됩니다. 이 헤더는 객체의 타입, 배열 형태, 내용과 관계없이 일정한 크기를 차지합니다. 현재 64비트 HotSpot JVM에서는 객체 헤더가 JVM 구성에 따라 96비트(12바이트)에서 128비트(16바이트)까지 차지합니다.
객체 헤더는 다음과 같은 중요한 정보를 포함합니다:
- 가비지 컬렉션 관련 정보 (포워딩 포인터, 객체 나이 등)
- 타입 시스템 (객체의 클래스 식별, 메서드 호출, 타입 체크에 사용)
- 락킹 정보 (경량 및 중량 락에 대한 정보)
- 해시 코드 (객체의 안정적인 식별 해시 코드)
컴팩트 객체 헤더의 메모리 효율성 측정 실험
100MB 크기의 힙에서 OutOfMemoryError를 인위적으로 발생시키는 실험을 통해 -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders
옵션의 효과를 측정해 보았습니다.
실험 설계
- 테스트 환경: Java 24 (amazon openjdk 24.0.0.36.2), Mac 시스템(sequoia), 최대 힙 크기 100MB
- 두 가지 시나리오 테스트:
- 기본 설정 (컴팩트 객체 헤더 비활성화)
- 컴팩트 객체 헤더 활성화 (
-XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders
)
- 많은 수의 작은 객체를 생성하여 OutOfMemoryError 유도
- 각 시나리오에서 생성된 객체 측정
실험 코드
import java.util.ArrayList;
import java.util.List;
public class MemoryTest {
public static void main(String[] args) {
long count = 0;
try {
List<Object> objects = new ArrayList<>();
while (true) {
objects.add(new Object());
count++;
}
} catch (OutOfMemoryError e) {
System.err.println("OutOfMemoryError occurred at count = " + count);
}
}
}
실험 결과 (M4-MAC)
기본 설정 (컴팩트 객체 헤더 비활성화)
$ java -Xmx100m MemoryTest
OutOfMemoryError occurred at count = 5132541
컴팩트 객체 헤더 활성화
$ java -Xmx100m -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders MemoryTest
OutOfMemoryError occurred at count = 6153400
실험 결과 (Rocky 8.10-x64)
기본 설정 (컴팩트 객체 헤더 비활성화)
$ java -Xmx100m MemoryTest
OutOfMemoryError occurred at count = 4102267
컴팩트 객체 헤더 활성화
$ java -Xmx100m -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders MemoryTest
OutOfMemoryError occurred at count = 6153400
실험 결과 (Win11-Arm64)
기본 설정 (컴팩트 객체 헤더 비활성화)
$ java -Xmx100m MemoryTest
OutOfMemoryError occurred at count = 4102267
컴팩트 객체 헤더 활성화
$ java -Xmx100m -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders MemoryTest
OutOfMemoryError occurred at count = 6153400
표
OS | 일반 | UseCompact |
---|---|---|
MAC | 5,132,541 | 6,153,400 |
Linux_x64 | 4,102,267 | 6,153,400 |
Win_arm64 | 4,102,267 | 6,153,400 |
분석
컴팩트 객체 헤더를 활성화했을 때 Mac기준 약 19.89%, Linux 및 Win11(Arm64)의 경우 50% 더 많은 객체를 생성할 수 있었습니다. 이는 JEP 450에서 예상한 대로 10~20% 정도의 메모리 절약 효과가 있음을 보여줍니다. ( Linux, Windows는 50% ?? )
특이한 점은 Mac과 Linux의 기본 설정 사용시 객체의 생성 가능한 개수가 다른 부분도 확인 할수 있었습니다. 또한 옵션을 사용시에는 동일한것으로 보아 옵션을 사용하면 JVM이 객체 헤더를 정확히 64비트(8바이트)로 표준화하기 때문에 플랫폼별 차이가 동일해지는 것을 확인할수 있습니다.
객체당 헤더 크기가 12~16바이트에서 8바이트로 줄어들면서, 같은 100MB 힙 공간에 더 많은 객체를 저장할 수 있게 되었습니다. 특히 작은 객체들이 많은 애플리케이션에서 이 효과는 더욱 두드러질것으로 보입니다.
실무적 의미
이 실험 결과는 다음과 같은 실무적인 의미를 갖습니다:
- 서버 비용 절감: 동일한 하드웨어에서 더 많은 객체를 처리할 수 있어 서버 비용을 절감할 수 있습니다.
- 성능 향상: 작은 객체들이 많은 애플리케이션에서 캐시 효율성이 향상되어 성능이 개선될 수 있습니다.
- GC 압력 감소: 전체적인 메모리 사용량이 감소하면서 가비지 컬렉션 발생 빈도가 줄어들고, 이는 특히 GC 일시 중지에 민감한 애플리케이션에서 중요합니다.
- 마이크로서비스 배포 밀도 증가: 각 마이크로서비스 인스턴스가 더 적은 메모리를 사용하므로, 동일한 인프라에서 더 많은 인스턴스를 실행할 수 있습니다.
고려사항 및 한계
- 실험적 기능: 현재 Java 24에서는 실험적 기능으로 제공되므로
-XX:+UnlockExperimentalVMOptions
플래그와 함께 사용해야 합니다. - 압축된 클래스 포인터 필요: 이 기능은 압축된 클래스 포인터가 활성화된 경우에만 작동합니다. 압축된 클래스 포인터를 비활성화하면 컴팩트 객체 헤더도 비활성화됩니다.
- 큰 힙 크기 제한: ZGC 이외의 가비지 컬렉터를 사용할 경우 8TB 이상의 힙에서는 컴팩트 객체 헤더가 비활성화됩니다.
- JVMCI 호환성: 현재 x64에서 JVMCI와 함께 사용할 경우 지원되지 않습니다.
결론
JEP 450: Compact Object Headers는 Java 애플리케이션의 메모리 효율성을 크게 향상시킬 수 있는 중요한 기능입니다. 실험 결과에 따르면 동일한 힙 크기에서 약 20%(50%) 더 많은 객체를 생성할 수 있었으며, 이는 대규모 Java 애플리케이션에서 상당한 비용 절감과 성능 향상으로 이어질 수 있습니다.
향후 Java 릴리스에서는 이 기능이 실험적 상태를 넘어 기본으로 활성화될 가능성이 높으며, 마이크로서비스 아키텍처와 클라우드 환경에서의 Java 애플리케이션 배포 및 운영에 큰 이점을 제공할 것으로 기대됩니다.
Edited by claude.ai
'Computer_IT > JAVA' 카테고리의 다른 글
Java 24 환경에서 guava / sun.misc.Unsafe 경고 메시지 (0) | 2025.03.20 |
---|---|
[Tomcat] Windows에서 콘솔 화면 한글 깨짐 조치 (0) | 2020.10.15 |
[MAVEN] unmappable character for encoding EUC_KR (0) | 2018.08.23 |
[spring] logback 로그 2번 찍힘 (0) | 2018.08.09 |
Java Bitmap pixel to image(png) setRGB example (0) | 2015.06.17 |