JDK 26 / OpenJDK 26
Java 26 직접 확인했습니다
— 새 언어 기능 0개인 이유
2026년 3월 17일 Java 26이 GA(정식 출시)됐습니다. JEP 10개가 포함됐는데, 막상 살펴보니 안정적(Stable) 언어 기능은 단 하나도 없었습니다. 이게 결함이 아니라 전략이라는 걸 공식 문서를 뜯어보고 나서야 이해했습니다.
Java 26, 언어 기능이 없다는 게 무슨 뜻인가
Java 26은 2026년 3월 17일 GA를 달성했습니다. JetBrains가 공식 블로그에 딱 이렇게 적었습니다: “Java 26 introduces no new stable language features.” (출처: JetBrains Blog, 2026.03.17) 버전 숫자가 올라갔는데 새 문법이 없다니 이상해 보이죠. 막상 이유를 들여다보면 납득이 됩니다.
Java의 6개월 릴리스 주기에서 언어 기능은 보통 프리뷰 → 재프리뷰 → 확정 단계를 밟습니다. Java 26에서 가장 주목할 언어 기능인 ‘패턴 매칭에서의 기본 타입(Primitive Types in Patterns)’ 은 Java 23부터 시작해서 이번이 네 번째 프리뷰입니다. 아직 확정이 안 됐다는 뜻입니다. 현재 Java 26의 언어 레벨 설정을 IntelliJ IDEA에서 확인하면 “26 – No new language features”라고 표시됩니다. (출처: JetBrains Blog, 2026.03.17)
💡 공식 릴리스 문서와 JetBrains 분석을 같이 놓고 보니 이런 구도가 보였습니다 — Java 26은 언어보다 런타임 기반을 다지는 릴리스입니다. 10개 JEP 중 5개가 성능·보안·인프라에 집중돼 있습니다.
반면 성능 개선은 지금 당장 코드 수정 없이 적용됩니다. 그 중 가장 체감 가능한 게 G1 GC 처리량 개선입니다.
G1 GC 처리량 — 이게 핵심입니다
JEP 522, G1 GC 처리량 개선은 이번 릴리스에서 가장 실질적인 변화입니다. G1은 Java 9 이후 기본 GC였는데, 애플리케이션 스레드와 GC 스레드가 동기화하는 구조 때문에 Parallel GC보다 처리량이 낮았습니다. Java 26에서 이 동기화 오버헤드를 획기적으로 줄였습니다.
객체 참조를 많이 수정하는 앱에서 최대 20% 빨라집니다
| 상황 | 처리량 향상 | 비고 |
|---|---|---|
| 객체 참조 필드를 자주 변경하는 앱 | 5~15% | JEP 522 본문 |
| x64 아키텍처 — write barrier 코드 단순화 효과 | 추가 ~5% | hanno.codes 분석, 2026.03.17 |
| 객체 참조 수정이 적은 일반 앱 | 미미 | 워크로드 의존 |
(출처: OpenJDK JEP 522 / hanno.codes Java 26 분석, 2026.03.17)
기술적으로는 카드 테이블(card table)을 두 개로 분리했습니다. 기존에는 애플리케이션 스레드와 GC 옵티마이저 스레드가 하나의 카드 테이블을 공유하면서 동기화 비용이 발생했는데, 이제 각각 독립 테이블을 사용합니다. 두 테이블이 차지하는 추가 메모리는 Java 힙 1GB당 약 2MB입니다. (출처: tschatzl.github.io, 2026.02.26) 2GB 힙 기준으로 4MB 메모리를 더 쓰고 처리량 최대 20%를 가져오는 셈입니다.
또 한 가지 — Java 26부터 G1의 기본 GC CPU 사용 목표가 8%에서 4%로 낮아졌습니다. (출처: tschatzl.github.io, 2026.02.26) G1이 그만큼 효율적으로 개선됐다는 방증입니다. 같은 일을 절반의 CPU 점유율로 처리합니다.
💡 코드 한 줄 안 건드려도 Java 26으로 올리면 GC가 빨라집니다. 특히 Spring Boot + JPA 앱처럼 엔티티 필드 업데이트가 잦은 서비스에서 체감 효과가 큽니다.
HTTP/3 지원 — 코드 한 줄로 얼마나 달라지나
JEP 517, HTTP/3 for the HTTP Client API는 Java 11에서 도입된 HttpClient API에 HTTP/3 지원을 추가합니다. HTTP/3는 TCP 기반의 HTTP/2와 달리 QUIC(UDP 기반) 위에서 동작해서 네트워크 혼잡 회피, 더 빠른 핸드셰이크, 연결 마이그레이션 같은 이점이 있습니다. 현재 웹 브라우저 대부분이 HTTP/3를 지원하고, 전체 웹사이트의 약 40%가 HTTP/3를 제공합니다. (출처: JetBrains Blog, 2026.03.17)
HTTP/3 옵트인은 이렇게 합니다
// HTTP/3 클라이언트 생성 var http3Client = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_3) .build(); // 단일 요청에만 적용 var request = HttpRequest.newBuilder(URI.create("https://example.com")) .version(HttpClient.Version.HTTP_3) .GET().build();
기존 코드에서 버전 설정 한 줄만 추가하면 됩니다. 서버가 HTTP/3를 지원하지 않으면 자동으로 HTTP/2 또는 HTTP/1.1로 폴백합니다. (출처: OpenJDK JEP 517)
단, 주의할 점이 있습니다. HTTP/3 협상 방식이 4가지인데, 각각 트레이드오프가 다릅니다. 가장 직관적인 방식(HTTP/3 먼저 시도, 실패 시 폴백)은 타임아웃 지연이 발생합니다. 두 연결을 동시에 열어 먼저 성공한 쪽을 쓰는 방식은 불필요한 TCP 연결 리소스 낭비가 생깁니다. (출처: hanno.codes Java 26 분석, 2026.03.17) HTTP/3가 확실히 지원되는 서버가 아니라면 기본 HTTP/2 유지가 나을 수도 있습니다.
Lazy Constants — 이름이 바뀐 데 이유가 있습니다
JEP 526 Lazy Constants(지연 상수)는 Java 25에서 ‘Stable Values(안정 값)’라는 이름으로 첫 프리뷰를 거쳤습니다. Java 26에서 이름이 바뀌었을 뿐만 아니라 API 구조도 크게 달라졌습니다. 저수준 메서드들(orElseSet, setOrThrow, trySet)이 제거됐고, 팩토리 메서드가 List와 Map 인터페이스로 이동했습니다. (출처: JetBrains Blog, 2026.03.17)
final 필드의 한계를 채우는 자리입니다
기존에 final 필드는 초기화를 생성자 또는 클래스 초기화 시점에 무조건 해야 했습니다. 필요 없을 수도 있는 무거운 객체까지 앱 시작 때 전부 초기화하니 기동 시간이 늘어났습니다. 그렇다고 null 체크를 쓰는 지연 초기화 패턴은 NPE 위험과 멀티스레드 문제가 있었습니다.
// 기존: 앱 시작 시 무조건 초기화 (느림) private final Logger logger = Logger.create(OrderController.class); // Java 26: 처음 필요할 때만 초기화, 스레드 안전, JVM 최적화 적용 private final LazyConstant<Logger> logger = LazyConstant.of(() -> Logger.create(OrderController.class));
LazyConstant.get()은 처음 호출될 때만 람다를 실행하고, 이후엔 캐시된 값을 반환합니다. 멀티스레드 환경에서도 딱 한 번만 실행을 보장합니다. JVM은 이 값을 final 선언과 동일하게 취급해 constant-folding 최적화까지 적용합니다. (출처: OpenJDK JEP 526)
단, 아직 두 번째 프리뷰 단계입니다. 프로덕션 코드에 쓰려면 --enable-preview 플래그가 필요하고, API가 Java 27에서 또 바뀔 수 있습니다. 지금은 사이드 프로젝트나 테스트 코드에서 감을 익히는 수준이 적절합니다.
AOT 캐시 확장 — ZGC와 드디어 함께 됩니다
JEP 516, Ahead-of-Time Object Caching with Any GC는 Project Leyden의 일환입니다. Java 24에서 AOT 캐시(클래스 로딩·링킹을 사전에 저장)가 도입됐는데, 당시엔 GC별로 캐시 포맷이 달라서 ZGC에선 쓸 수 없었습니다. Java 26에서 캐시 포맷을 GC 독립적으로 바꿔 모든 GC에서 쓸 수 있게 됐습니다. (출처: OpenJDK JEP 516)
ZGC 쓰는 컨테이너 환경이 직접 혜택을 받습니다
저지연 요구사항으로 ZGC를 선택한 서비스들, 특히 쿠버네티스 환경의 Java 마이크로서비스가 직접 혜택을 받습니다. 이제 AOT 캐시와 ZGC를 함께 쓰면 스타트업 시간 단축과 저지연 GC를 동시에 누릴 수 있습니다. (출처: Oracle 공식 보도자료, 2026.03.17)
새 GC-agnostic 포맷을 강제로 사용하려면 -XX:+AOTStreamableObjects 옵션을 추가하면 됩니다. 단, 새 포맷은 기동 시 객체를 스트리밍 방식으로 메모리에 로드하기 때문에 기존 GC 특정 포맷보다 초기 로딩에 약간 더 시간이 걸릴 수 있습니다. Oralce 공식 문서에서 별도 수치를 밝히지 않은 부분입니다.
Non-LTS라고 건너뛰면 잃는 것들
Java 26은 LTS가 아닙니다. 직전 LTS는 Java 25(2025년 9월)입니다. “LTS 아니면 안 써”라는 입장이 기업에선 일반적이죠. 그런데 이번엔 다릅니다. G1 GC 처리량 개선, AOT 캐시의 ZGC 지원, HTTP/3 — 이 세 가지는 코드 변경 없이 성능을 올려주는 런타임 개선입니다. (출처: The New Stack, 2026.03.18)
⚠️ Non-LTS의 실제 리스크는 이겁니다:
- 6개월 후 Java 27이 나오면 Oracle의 Premier Support가 종료됩니다.
- 프리뷰 기능(Lazy Constants, PEM API 등)의 API가 다음 버전에서 바뀔 수 있습니다.
- 일부 서드파티 프레임워크가 non-LTS 버전 공식 지원을 늦게 추가합니다.
결국 “Java 26을 프로덕션에 쓸까”는 팀의 업그레이드 주기 전략에 달렸습니다. 6개월마다 업그레이드하는 팀이라면 G1 GC 성능 이득을 지금 당장 챙길 수 있습니다. LTS만 쓰는 팀이라면 Java 25에서 G1 GC 기본값 변화(GC CPU 목표 8% → 4%)는 이미 적용됐으니, AOT 캐시 ZGC 지원과 HTTP/3는 다음 LTS인 Java 27 또는 28을 기다리는 게 맞습니다.
5년째 인큐베이터 — Vector API의 실전 활용 판단법
JEP 529 Vector API는 이번이 열한 번째 인큐베이터(Incubator)입니다. Java 16(2021년 3월)에 처음 등장한 이후 매 버전 인큐베이터를 반복하고 있습니다. (출처: InfoWorld, 2026.03.17) Java 16에서 첫 인큐베이터였으니, 5년이 지난 지금도 완성이 안 됐다는 뜻입니다.
💡 Vector API가 5년째 인큐베이터인 이유를 공식 문서에서 찾았습니다 — “Project Valhalla의 value class 기능이 준비되면 그에 맞게 API를 개편한 뒤 프리뷰로 승격할 예정”이라고 JEP 529에 직접 명시돼 있습니다. Valhalla 없이는 확정 불가 구조입니다.
실전 판단법은 간단합니다. 머신러닝 추론 엔진, 선형대수 라이브러리, 고성능 암호화 처리처럼 SIMD 연산이 직접 필요한 특수 영역이라면 11번째 인큐베이터라도 지금 당장 벤치마킹해볼 이유가 있습니다. 일반 비즈니스 로직이라면 인큐베이터 API가 계속 바뀌므로 프로덕션 의존은 피하는 게 낫습니다.
JetBrains IntelliJ IDEA 2026.1에서 Java 26 지원이 첫날부터 제공됩니다. Vector API를 쓰려면 VM 옵션에 --add-modules jdk.incubator.vector를 추가해야 합니다. (출처: JetBrains Blog, 2026.03.17)
Q&A
마치며
Java 26을 직접 들여다보고 나서 든 생각을 솔직히 말하면, 처음엔 “언어 기능 0개면 볼 게 없는 거 아닌가” 싶었습니다. 그런데 G1 GC 처리량이 최대 20% 올라가는 건 체감이 가능한 수치고, AOT 캐시가 ZGC에서 드디어 작동한다는 건 컨테이너 환경에서 실질적인 변화입니다. HTTP/3 지원도 코드 한 줄로 쓸 수 있는 수준이 됐습니다.
언어보다 런타임이 먼저 탄탄해져야 한다는 게 이번 릴리스의 메시지인 것 같습니다. Project Valhalla의 value class가 나올 때 Vector API도 함께 확정되고, Lazy Constants도 그 즈음에 안정화될 겁니다. 큰 그림으로 보면 Java 26은 그 준비 단계입니다.
LTS 팀이라면 Java 25 베이스에서 GC 튜닝 파라미터가 바뀐 것(InitialRAMPercentage 기본값 0으로 변경 등)은 한 번 점검해두는 게 좋습니다. 컨테이너 배포 환경에서 예상치 못한 힙 설정 변화가 생길 수 있습니다.
본 포스팅 참고 자료
- Oracle 공식 보도자료 — Oracle Java 26 출시 (2026.03.17)
- OpenJDK 공식 — JDK 26 Features & Schedule
- JetBrains 기술 블로그 — Java 26 in IntelliJ IDEA (2026.03.17)
- Thomas Schatzl (GC 엔지니어) — JDK 26 G1/Parallel/Serial GC Changes (2026.02.26)
- hanno.codes — Java 26 Is Here (2026.03.17)
- InfoWorld — JDK 26: The new features in Java 26
본 포스팅은 2026년 3월 21일 기준 공개된 Oracle, OpenJDK, JetBrains 공식 문서를 바탕으로 작성됐습니다. 본 포스팅 작성 이후 서비스 정책·API·기능이 변경될 수 있습니다. Java 버전 업그레이드 전 공식 릴리스 노트를 반드시 확인하시기 바랍니다.

댓글 남기기