Java 25는 LTS(장기 지원) 릴리스로, 현재 Java 8, 11, 17 또는 21에서 실행되는 팀의 자연스러운 목표입니다. 각 LTS 릴리스는 수년간의 업데이트 및 보안 수정 사항을 받으므로 Java 25로 전환하면 애플리케이션이 지원되고 안전하며 최신 성능 및 언어 향상을 사용할 수 있습니다.
문제는 최신 LTS 릴리스로 이동해야 하는지 가 아니라시기입니다. 대기 시간이 길어질수록 현재 버전과 지원되는 다음 버전 간에 더 많은 변경 내용이 누적됩니다. Java 25로 전환하면 분명한 이점이 있으며, 전환 계획을 늦기보다 빨리 세울수록 위험을 줄일 수 있습니다.
Java 8부터 모든 릴리스에는 기능과 향상된 기능이 추가되었습니다. 시작 시간, 처리량, 메모리 사용량, 확장성 및 개발자 생산성 향상과 함께 API에 눈에 띄는 추가 및 수정이 있습니다. 이 문서에서는 Java 11 LTS 릴리스(Java 17, Java 21, Java 25) 이후 제공되는 Java 버전에 중점을 두고 가장 영향력 있는 변경 내용을 강조 표시합니다.
Java 25로 전환
단계별 방식으로 Java 25로 전환할 수 있습니다. 이전 JDK를 사용하여 개발 및 빌드된 코드는 일반적으로 다시 컴파일하지 않고 Java 25에서 실행할 수 있습니다. 주요 업그레이드와 마찬가지로, 특히 가비지 수집과 관련하여 제거된 API, 사용되지 않는 패키지, 내부 API 사용 및 기본 동작의 변경 내용을 확인합니다.
Java 8 또는 11에서 업그레이드하는 경우, 가장 많은 호환성 깨짐 변경 사항에 대응하려면 먼저 Java 8에서 Java 11로 전환 가이드부터 시작한 다음 Java 17, 21, 25로 계속 진행하세요. 이미 Java 17 또는 21에 있는 경우 모듈 시스템과 대부분의 플랫폼 변경 내용이 이미 뒤에 있기 때문에 Java 25로 이동하는 것이 일반적으로 더 작습니다.
팁 (조언)
GitHub Copilot 앱 현대화를 통해 애플리케이션을 평가하고, 업그레이드를 계획하고, 코드 변경 내용을 자동으로 적용할 수 있습니다. Java 버전 8, 11, 17, 21 및 25 간의 업그레이드를 지원하고, 각 변경 후 프로젝트를 빌드하고 테스트하며, 이 문서의 뒷부분에 설명된 동작 변경 내용을 수정하는 데 도움이 됩니다.
팁 (조언)
이전 JDK에 맞춰 조정된 JVM 플래그는 Java 25에서는 더 이상 사용되지 않거나 제거되거나 최적이 아닐 수 있습니다. 부실 설정을 전달하는 대신 Azure 명령 시작 관리자 Java()가 JDK 버전 및 컨테이너 또는 가상 머신 리소스에 맞게 조정된 JVM 플래그를jaz 자동으로 적용하도록 할 수 있습니다.
java 명령을 jaz 시작 스크립트에서 바꾸거나 Dockerfile 이점을 얻을 수 있습니다.
Java 11 이후 상위 수준 변경
이 섹션에서는 Java 8 이후의 모든 변경 내용을 열거하지는 않습니다. 성능, 확장성, 진단, 생산성 및 보안에 가장 큰 영향을 주는 변경 사항을 강조 표시합니다. 이러한 기능의 대부분은 Java 17, 21 및 25 릴리스에 도착했으며 이제 Java 25와 함께 제공되는 LTS 기준의 일부입니다. 각 기능은 통합된 Java 릴리스를 확인합니다.
가상 스레드를 사용하는 확장성
가상 스레드 [1]는 운영 체제가 아닌 JVM에서 관리하는 경량 스레드로, 처리량이 높은 동시 애플리케이션을 작성하고 실행하는 비용을 크게 줄입니다. 가상 스레드를 사용하면 간단한 요청당 스레드 스타일로 코드를 작성할 수 있으며 여전히 많은 수의 동시 작업으로 확장할 수 있으며 이는 I/O 바인딩된 마이크로 서비스 및 요청-응답 워크로드에 적합합니다.
가상 스레드는 Java 21에서 완료되었습니다. Java 24는 가상 스레드가 통신 사업자 스레드 [2]를 고정하지 않고 동기화할 수 있도록 하여 주요 제한을 제거하여 블록을 사용하는 synchronized 코드의 확장성을 향상시켰습니다.
구조적 동시성 및 범위가 지정된 값
범위가 지정된 값 [3]은 가상 스레드를 포함하여 스레드 내 및 스레드 간에 변경할 수 없는 데이터를 공유하는 안전하고 효율적인 방법을 제공합니다. 태스크별 스레드 모델에서 잘 작동하는 스레드 지역 변수에 대한 최신 대안입니다.
구조적 동시성 [4]은 관련된 동시 작업 그룹을 단일 작업 단위로 처리하여 오류 처리 및 취소를 간소화합니다. Java 21에서 처음 미리 보기된 이 기능은 계속 진화하고 가상 스레드와 자연스럽게 쌍을 이루게 됩니다.
언어 생산성
Java 14에서 Java 25까지 제공되는 일련의 언어 개선 사항으로 코드가 더 간결하고 안전하며 읽기 쉽습니다.
-
스위치 식 [5](Java 14)를 사용하면 값을 반환하고 더 깨끗한 화살표 구문을 사용할 수
switch있습니다. -
에 대한
instanceof패턴 일치 [6](Java 16)은 형식 검사 후 명시적 캐스트의 필요성을 제거합니다. - 레코드 [7] (Java 16)는 고정된 값 집합을 위한 투명한 전달자로서 불변 데이터를 모델링하여 반복 코드를 줄입니다.
- 봉인된 클래스 [8](Java 17)을 사용하면 형식을 확장하거나 구현할 수 있는 클래스를 제어할 수 있습니다.
- 텍스트 블록 [9](Java 15)는 여러 줄 문자열 리터럴을 간소화합니다.
-
에 대한
switch패턴 일치 [10](Java 21) 및 레코드 패턴 [11](Java 21)을 사용하면 복잡한 조건부 논리 및 데이터 소멸을 명확하고 안전하게 표현할 수 있습니다. - 시퀀스된 컬렉션 [12](Java 21)은 첫 번째 요소와 마지막 요소에 대한 액세스를 포함하여 정의된 만남 순서를 가진 컬렉션에 대한 균일한 API를 추가합니다.
- 명명되지 않은 변수 및 패턴 [13](Java 22)을 사용하면 사용되지 않는 변수 및 패턴 구성 요소를 명시적으로 표시할 수 있습니다.
- 모듈 가져오기 선언 [14](Java 25)을 사용하면 단일 선언으로 전체 모듈의 내보낸 패키지를 가져올 수 있습니다.
- 압축 소스 파일 및 인스턴스 기본 방법 [15](Java 25)은 작은 프로그램에 필요한 의식을 줄여 Java 더 쉽고 빠르게 프로토타입을 학습할 수 있도록 합니다.
-
유연한 생성자 본문 [16](Java 25)을 사용하면 호출
super(...)하기 전에 문을 실행하거나this(...)유효성 검사 및 초기화를 향상시킬 수 있습니다.
성능 및 시작
몇 가지 런타임 변경으로 처리량, 메모리 공간 및 시작 시간이 향상됩니다.
- 압축 개체 헤더 [17](Java 25)는 64비트 플랫폼에서 개체 헤더의 크기를 줄입니다. 이렇게 하면 힙 사용량이 줄어들고 할당이 많은 워크로드의 성능이 향상될 수 있습니다.
- CDS(클래스 데이터 공유) 는 런타임에 보관된 클래스를 메모리 매핑하여 시작 시간을 낮춥니다. 기본 CDS 보관 파일 [18](Java 12) 및 동적 CDS 보관 파일 [19](Java 13)을 사용하면 수동 학습 실행 없이 이 기능을 더 쉽게 채택할 수 있습니다.
- 사전 클래스 로딩 및 링크 [20] (Java 24)는 사전 명령줄 사용성 개선 [21] (Java 25) 및 사전 메서드 프로파일링 [22] (Java 25)과 함께 애플리케이션 아카이브에 저장된 작업을 재사용하여 시작 시간과 워밍업 시간을 단축합니다. 이러한 기능은 Java 더 빨리 시작하기 위한 Project Leyden의 노력의 일부입니다.
이러한 개선 사항은 클라우드 네이티브 및 서버리스 워크로드에 특히 유용하며, 빠른 시작과 작은 공간은 더 나은 크기 조정과 저렴한 비용으로 직접 변환됩니다.
쓰레기 수거
Java 25는 다양한 워크로드에 적합한 성숙한 저지연 가비지 컬렉터를 함께 제공합니다.
- ZGC [23](Java 15)와 셰넌도어 [24](Java 15)는 큰 힙에서 낮은 일시 중지 시간을 위해 설계된 프로덕션 준비 수집기입니다.
- G1GC는 기본 수집기로 남아 있으며 네이티브 코드와의 원활한 상호 작용을 위해 지역 고정 [25](Java 22)을 포함하여 계속해서 개선 사항을 받고 있습니다.
- 세대 ZGC [26](Java 21)은 별도의 세대를 유지 관리하여 효율성을 향상시킵니다. Java 23일부터 ZGC는 기본적으로 세대 모드 [27]에서 실행되며 비세대 모드는 Java 24에서 제거되었습니다.
- 세대별 Shenandoah [28](Java 25)는 메모리 압력 하에서 더 나은 처리량과 복원력을 위해 Shenandoah 수집기에 세대 모드를 추가합니다.
JVM은 평균 사용 사례에 대한 GC 기본값을 설정합니다. 이러한 기본값 및 기타 GC 설정을 조정하여 애플리케이션의 요구 사항에 따라 처리량 또는 대기 시간을 최적화합니다.
팁 (조언)
기본 가비지 수집기와 많은 JVM 기본값은 Java 버전마다 다르므로 Java 8 또는 11로 조정된 설정은 Java 25에서 더 이상 최적이 아닐 수 있습니다.
Java Azure 명령 시작 관리자(jaz)는 컨테이너의 cgroup 메모리 및 CPU 제한을 읽고 JDK 버전 및 환경에 맞게 조정된 JVM 플래그를 자동으로 적용합니다.
진단 및 관찰 가능성
언어 및 JFR(Java Flight Recorder)에서 릴리스 간에 진단이 개선되었습니다.
-
Helpful NullPointerExceptions [29] (Java 14)는 어떤 변수가
nullnull이었는지를 정확히 설명하여 디버깅 속도를 높입니다. - JFR 이벤트 스트리밍 [30](Java 14)을 사용하면 도구가 덤프 파일 대신 프로파일링 및 진단 데이터를 지속적으로 사용할 수 있습니다.
- JFR CPU 시간 프로파일링 [31](Java 25)은 Linux에서 실험적 CPU 시간 기반 메서드 프로파일링을 추가합니다.
- JFR 협조 샘플링 [32](Java 25)은 스택 샘플링의 안정성을 향상시킵니다.
- JFR 메서드 타이밍 및 추적 [33](Java 25)을 사용하면 애플리케이션 코드를 수정하지 않고도 특정 메서드를 시간 및 추적할 수 있습니다.
보안 및 암호화
Java 25는 양자 이후 세계에 대한 준비를 포함하여 플랫폼의 보안 태세를 강화합니다.
- Edwards-Curve 디지털 서명 알고리즘(EdDSA) [34](Java 15)은 최신 고성능 서명 체계를 추가합니다.
- 키 캡슐화 메커니즘 API [35](Java 21)는 KEM 알고리즘에 대한 표준 API를 제공합니다.
- 양자 내성 암호화는 모듈 격자 기반 키 캡슐화 메커니즘(ML-KEM) [36](Java 24) 및 디지털 서명 알고리즘(ML-DSA) [37](Java 24)의 표준 구현을 추가합니다.
- 키 파생 함수 API [38](Java 25)는 키 파생 함수에 대한 표준 API를 제공합니다.
내재적 상호 운용성
외래 함수 및 메모리 API [39](Java 22)는 네이티브 라이브러리를 호출하고 네이티브 메모리에 액세스하는 안전하고 효율적이며 순수 Java 방법을 제공합니다. 상용구가 줄어들고 안전성을 향상시키는 JNI(Java 네이티브 인터페이스)를 최신으로 대체합니다.
도구 및 라이브러리
몇 가지 추가는 일상적인 개발을 개선하고 타사 도구의 필요성을 줄입니다.
-
패키징 도구(
jpackage) [40](Java 16)는 Java 애플리케이션에 대한 네이티브 설치 관리자 및 패키지를 만듭니다. - 간단한 웹 서버 [41](Java 18)는 프로토타입 생성 및 테스트를 위한 최소 정적 파일 HTTP 서버를 제공합니다.
- 향상된 의사 난수 생성기 [42] (Java 17)는 난수 생성을 위한 새로운 인터페이스와 구현을 도입합니다.
대비해야 할 동작 방식 변경 사항
Java 11 이후의 일부 변경 내용은 기본 동작을 변경하므로 업그레이드하기 전에 검토하세요.
-
JDK 내부 [43](Java 17)를 강력하게 캡슐화하면 기본적으로 대부분의 내부 API에 대한 반사 액세스가 차단됩니다.
sun.*또는 다른 내부 패키지에 접근하는 코드나 라이브러리는 업데이트가 필요할 수 있습니다. - 기본적으로 UTF-8 [44](Java 18)은 표준 Java API의 기본 문자 집합으로 UTF-8을 만듭니다. 플랫폼별 기본 문자 집합에 의존하는 애플리케이션은 다르게 동작할 수 있습니다.
-
제거 예정으로 finalization을 deprecated 처리 [45] (Java 18)은
finalize()가 결국 제거될 것임을 나타냅니다.try-with-resources 또는java.lang.ref.Cleaner로 마이그레이션하세요. - 에이전트의 동적 로드를 허용하지 않도록 준비 [46] (Java 21)는 에이전트가 실행 중인 JVM에 로드될 때 경고합니다. 일부 모니터링 및 계측 도구에는 구성 변경이 필요할 수 있습니다.
팁 (조언)
GitHub Copilot 앱 현대화를 통해 업그레이드할 때 이러한 동작 변경 내용을 자동으로 평가하고 수정할 수 있습니다.
컨테이너 및 클라우드
Docker 및 기타 컨테이너 런타임에 도입된 JVM의 컨테이너 인식은 계속 개선되고 있습니다. JVM은 컨테이너 제어 그룹(cgroups)에서 설정한 CPU 및 메모리 제약 조건을 읽고 그에 따라 힙 및 기타 리소스의 크기를 조정합니다. 더 빠른 시작, 더 작은 공간 및 가상 스레드와 결합된 Java 25는 Azure 컨테이너화된 서버리스 배포에 적합합니다.
Azure 컨테이너 또는 가상 머신에서 Java 워크로드를 실행하는 경우 Java 대한 Azure 명령 시작 관리자(jaz)는 클라우드 최적화 버전에 적합한 JVM 기본값을 적용할 수 있습니다.
다음 단계
References
[1] Oracle Corporation, "JEP 444: Virtual Threads." (온라인). 사용 가능: https://openjdk.org/jeps/444.
[2] Oracle Corporation, "JEP 491: 고정 없이 가상 스레드 동기화." (온라인). 사용 가능: https://openjdk.org/jeps/491.
[3] Oracle Corporation, "JEP 506: 범위가 지정된 값." (온라인). 사용 가능: https://openjdk.org/jeps/506.
[4] Oracle Corporation, "JEP 453: 구조적 동시성(미리 보기)." (온라인). 사용 가능: https://openjdk.org/jeps/453.
[5] Oracle Corporation, "JEP 361: Switch Expressions." (온라인). 사용 가능: https://openjdk.org/jeps/361.
[6] Oracle Corporation, "JEP 394: instanceof에 대한 패턴 일치" (온라인). 사용 가능: https://openjdk.org/jeps/394.
[7] Oracle Corporation, "JEP 395: Records." (온라인). 사용 가능: https://openjdk.org/jeps/395.
[8] Oracle Corporation, "JEP 409: 봉인된 클래스." (온라인 자료). 사용 가능: https://openjdk.org/jeps/409.
[9] Oracle Corporation, "JEP 378: Text Blocks." (온라인). 사용 가능: https://openjdk.org/jeps/378.
[10] Oracle Corporation, "JEP 441: 스위치에 대한 패턴 일치" (온라인). 사용 가능: https://openjdk.org/jeps/441.
[11] Oracle Corporation, "JEP 440: 레코드 패턴." (온라인). 사용 가능: https://openjdk.org/jeps/440.
[12] Oracle Corporation, "JEP 431: Sequenced Collections." (온라인). 사용 가능: https://openjdk.org/jeps/431.
[13] Oracle Corporation, "JEP 456: 명명되지 않은 변수 및 패턴." (온라인). 사용 가능: https://openjdk.org/jeps/456.
[14] Oracle Corporation, "JEP 511: 모듈 가져오기 선언" (온라인). 사용 가능: https://openjdk.org/jeps/511.
[15] Oracle Corporation, "JEP 512: Compact Source Files and Instance Main Methods." (온라인). 사용 가능: https://openjdk.org/jeps/512.
[16] Oracle Corporation, "JEP 513: 유연한 생성자 본문." (온라인). 사용 가능: https://openjdk.org/jeps/513.
[17] Oracle Corporation, "JEP 519: 압축 객체 헤더." (온라인). 사용 가능: https://openjdk.org/jeps/519.
[18] Oracle Corporation, "JEP 341: 기본 CDS 아카이브." (온라인). 사용 가능: https://openjdk.org/jeps/341.
[19] Oracle Corporation, "JEP 350: 동적 CDS 아카이브." (온라인). 사용 가능: https://openjdk.org/jeps/350.
[20] Oracle Corporation, "JEP 483: 사전 클래스 로딩 및 링킹." (온라인). 사용 가능: https://openjdk.org/jeps/483.
[21] Oracle Corporation, "JEP 514: 사전 컴파일 명령줄 사용성." (온라인). 사용 가능: https://openjdk.org/jeps/514.
[22] Oracle Corporation, "JEP 515: 사전 메서드 프로파일링." (온라인). 사용 가능: https://openjdk.org/jeps/515.
[23] Oracle Corporation, "JEP 377: ZGC: 확장 가능한 저지연 가비지 컬렉터." (온라인). 사용 가능: https://openjdk.org/jeps/377.
[24] Oracle Corporation, "JEP 379: Shenandoah: 짧은 일시 중지 시간의 가비지 수집기." (온라인). 사용 가능: https://openjdk.org/jeps/379.
[25] Oracle Corporation, "JEP 423: G1에 대한 지역 고정" (온라인). 사용 가능: https://openjdk.org/jeps/423.
[26] Oracle Corporation, "JEP 439: Generational ZGC." (온라인 문서). 사용 가능: https://openjdk.org/jeps/439.
[27] Oracle Corporation, "JEP 474: ZGC: Generational Mode by Default." (온라인). 사용 가능: https://openjdk.org/jeps/474.
[28] Oracle Corporation, "JEP 521: Generational Shenandoah." (온라인). 사용 가능: https://openjdk.org/jeps/521.
[29] Oracle Corporation, "JEP 358: Helpful NullPointerExceptions." (Online). 사용 가능: https://openjdk.org/jeps/358.
[30] Oracle Corporation, "JEP 349: JFR 이벤트 스트리밍." (온라인). 사용 가능: https://openjdk.org/jeps/349.
[31] Oracle Corporation, "JEP 509: JFR CPU-Time 프로파일링 (실험적)." (온라인). 사용 가능: https://openjdk.org/jeps/509.
[32] Oracle Corporation, "JEP 518: JFR 협력 샘플링." (온라인). 사용 가능: https://openjdk.org/jeps/518.
[33] Oracle Corporation, "JEP 520: JFR 메서드 타이밍 및 추적." (온라인). 사용 가능: https://openjdk.org/jeps/520.
[34] Oracle Corporation, "JEP 339: Edwards-Curve 디지털 서명 알고리즘(EdDSA)" (온라인). 사용 가능: https://openjdk.org/jeps/339.
[35] Oracle Corporation, "JEP 452: 키 캡슐화 메커니즘 API." (온라인). 사용 가능: https://openjdk.org/jeps/452.
[36] Oracle Corporation, "JEP 496: 양자 내성 모듈 격자 기반 키 캡슐화 메커니즘." (온라인). 사용 가능: https://openjdk.org/jeps/496.
[37] Oracle Corporation, "JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm." (온라인). 사용 가능: https://openjdk.org/jeps/497.
[38] Oracle Corporation, "JEP 510: 키 파생 함수 API." (온라인). 사용 가능: https://openjdk.org/jeps/510.
[39] Oracle Corporation, "JEP 454: Foreign Function & Memory API." (온라인). 사용 가능: https://openjdk.org/jeps/454.
[40] Oracle Corporation, "JEP 392: 패키징 도구." (온라인). 사용 가능: https://openjdk.org/jeps/392.
[41] Oracle Corporation, "JEP 408: Simple Web Server." (온라인). 사용 가능: https://openjdk.org/jeps/408.
[42] Oracle Corporation, "JEP 356: 향상된 Pseudo-Random 수 생성기." (온라인). 사용 가능: https://openjdk.org/jeps/356.
[43] Oracle Corporation, "JEP 403: JDK Internals를 강력하게 캡슐화합니다." (온라인). 사용 가능: https://openjdk.org/jeps/403.
[44] Oracle Corporation, "JEP 400: UTF-8 by Default." (온라인). 사용 가능: https://openjdk.org/jeps/400.
[45] Oracle Corporation, "JEP 421: 제거를 위해 Finalization을 폐기 예정으로 지정." (온라인). 사용 가능: https://openjdk.org/jeps/421.
[46] Oracle Corporation, "JEP 451: 에이전트의 동적 로딩을 허용하지 않도록 준비." (온라인). 사용 가능: https://openjdk.org/jeps/451.