본문 바로가기

Java

[Java] 버전별 업데이트 사항

이번 장에서는 자바 버전에 따른 변경사항과 트렌드에 대해서 알아본다.
대부분 기계인간 John Grib과 Oracle 공식문서를 참고하여 작성하였으며 Java 7 이후 버전에 대한 정리만 진행한다.
주요 변경사항이라고 표시한 부분은 어디까지나 스프링 기반 백엔드 개발자인 필자의 개인적인 의견일 뿐(예를 들어Swing관련 큰 변화가 있어도 필자에게는 크게 느껴지지 않는다.)이며 보는 관점에 따라서 달라질 수 있다.


* 개요

필자가 재직 중인 회사에 새로운 프로젝트를 진행하게 되면서 자바의 버전을 선택해야하는 시간을 가지게 되었다.
지금까지 사용해왔고 편한 8, 11을 사용할 수는 있겠지만 요즘 자바와 코틀린이 빠르게 성장하며 자바의 버전도 빠르게 업데이트 되고 있기 때문에 버전별로 업데이트 된 사항들을 정리하는 시간을 가져보도록 한다.
이전과는 다르게 현시대의 자바 개발자들은 자바 버전에 관심을 가지고 개발을 해야한다. 아래의 이미지는 Wikipedia에 나와있는 자바 버전 이력이다.

주의깊게 봐야하는 부분은 JDK Beta에서 Java SE 7까지 총 9개의 버전을 출시하는데 16년이라는 시간이 걸렸다.
하지만 Java SE 8(LTS)부터 Java SE 17(LTS)까지 총 10개의 버전을 출시하는데 이전의 절반도 안되는 7년이라는 시간이 걸렸다.
밑에서 다루겠지만 Java 17이후 부터는 LTS 출시 간격을 3년에서 2년으로 줄인다는 발표까지 진행되었다.
(Oracle이 Sun을 2009년 쯤에 인수하고 처음으로 Java 7을 출시하였으니 이때를 시작으로 빠른 버전업이 진행되었다고 보는 것이 맞을 듯 하다.)
이렇게 빠르게 자바의 버전이 변경되며 새로운 문법과 새로운 GC 등등 새로운 기능들이 판을 치는 자바 생태계에 버전에 따른 변경사항을 공부하는 것은 어떻게 보면 당연하다.

여담이지만 이렇게 글을 정리하는 가장 큰 이유는 자바의 버전별 변경사항이 인터뷰 질문에 자주 등장하기 때문이다.
작성일 기준 1년 전쯤 "자바8에서 변경된 사항이 무엇인가요?" 라는 인터뷰 질문에 필자는 "Stream과 Optional이 추가되었습니다."라는 답변을 하였다.
답변을 들은 면접관은 "자바8에서 변경사항이 많이 있을텐데 다른 건 없나요???"라고 질문하였고 필자는 입을 다물 수 밖에 없었다.

이 글을 읽는 사람들은 필자와 같은 실수를 하지 않았으면 하는 바램으로 변경사항을 정리하며 인터뷰 질문에 대한 답변도 정리하는 시간을 가져보려 한다.
모든 변경사항을 다루지는 않으며 인터뷰 질문을 대비한 "주요 변경사항"과 JVM 관련 변경사항 및 기타 변경사항에 대해서 알아본다.

보안(Security)관련 업데이트는 내용이 너무 길어져서 추후 따로 정리하도록 한다.


* Java 8(LTS)

* 주요 변경사항

  • Lambda Expressions:
    메소드를 하나의 식으로 표현한 람다 표현식이 등장하였다. 익명 함수라고도 불리며 코드를 사용 이전보다 깔끔하게 만들어준다는 장점이 있다.
    특히 구현해야하는 메서드가 하나 뿐인 인터페이스를 구현하는 경우에 이전보다 훨씬 간략하게 코드를 작성할 수 있다.

  • Functional Interface:
    구현해야하는 추상 메서드를 단 하나만 가지고 있는 인터페이스를 의미한다. 이러한 인터페이스를 람다 표현식과 함께 간편하게 사용할 수 있다.

  • Interface Default Method:
    추상 클래스와 같이 인터페이스에도 default 메서드가 추가되어 구현된 메서드를 가질 수 있다.

  • Stream:
    순차 및 병렬 집계 작업을 도와주는 Collections의 Stream 추가, 병렬 작업으로 다중 코어에서의 성능 향상

  • Optional:
    NPE방지를 위한 새로운 타입의 Optional 클래스 추가

  • DateTime Package:
    java.time 경로에 Data-Time 패키지 추가

* JVM 관련 변경사항

  • AES(Advanced Encryption Standard) 내장 기능 추가

  • PermGen 제거

* 기타 변경사항

  • @Repeatable Annotation:
    중복되는 애노테이션 사용으로 인한 중복 코드를 제거하기 위해 @Repeatable 애노테이션 추가

  • Improved type inference:
    타입 추론 성능 향상

  • Method parameter reflection:
    메소드 또는 생성자의 매개변수 이름을 가져올 수 있는 기능 추가

  • HashMap 성능 향상: 중복 키에 대한 성능 향상

  • java.util.concurrent 개선: 새로운 인터페이스와 클래스 추가 및 람다 표현식 지원

  • CompletableFuture-Future: 인터페이스에서 제공하는 기능 개선

  • IO/NIO 개선: java.lang.String(byte[], *), java.lang.String.getBytes() 메서드 퍼포먼스 향상

  • java.util 패키지에 Parallel Array Sorting 추가

* 정리

Java8의 핵심 변경사항은 람다 표현식, Stream, Optional 정도가 될 듯하다.

JVM 메모리 구조에 대한 인터뷰 질문도 많이 나오는데 Java8에서 PermGen이 제거되었다는 것을 기억하고 PermGen에 대한 언급은 하지 않거나 언급하게 된다면 Java8에서 삭제되었다고 얘기해야한다.

Concurrent, Parallel, Stream, CompletableFuture 모두 다중 스레드를 염두한 동시처리 및 병렬처리와 관련이 있다.
하드웨어 성능 향상으로 다중 코어 및 다중 스레드에 초점을 맞추어 Java도 발전하고 있는 것을 볼 수 있다.

Java8 핵심 키워드: 람다 표현식, 함수형 인터페이스, DateTime, Concurrent, Parallel, Stream


Java 9

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

* 정리

새로운 버전의 발표주기가 6개월로 변경되었다는 표현이 기존보다 짧은 주기로 업데이트가 이뤄진다는 의미처럼 보이지만 그렇지는 않다.
예를 들어 java8은 2014년 3월에 출시되었고 기능 릴리즈인 8u20은 2014년 8월에 출시되었다. 다음 릴리즈는 8u40으로 6개월 후에 출시되었다.
결국 기존에 6 ~ 8개월마다 기능 릴리즈가 있던 것을 6개월로 고정한다는 의미로 보면 될 듯하다.

CMS GC는 Deprecated되었고 기본 GC가 Parallel GC에서 G1GC로 변경되었다.
결국 자바는 메모리 단편화 문제를 해결하지 못한 CMS GC를 실패작으로 판단하고 G1GC를 표준으로 밀고 나가려는 것으로 보인다.
만약 인터뷰를 진행하려는 회사가 자바9 이상 버전을 쓰고 있다면 JVM 메모리 구조나 GC 과정에 대한 답변을 G1GC의 메커니즘에 맞춰야 한다.

이번에도 CompletableFuture가 개선되었으며 비동기 반응형 API인 Reactive Streams가 추가되었다.
본격적으로 자바도 비동기 프로그래밍의 시대를 열 것으로 예상된다.

공식문서에 따르면 Java9에서의 가장 큰 변화는 Java 프로그래밍 구성 요소인 모듈 추가라고 한다.
사실 이 부분에 대해서는 이해도 어렵고 분석하는데 시간이 많이 소요될 듯 하여 링크만 남겨두고 분석은 미루도록 한다.
Java Platform Module System(JSR 376)
Module System(JEP 261)
The Modular JDK(JEP 200)
Modular Run-Time Images(JEP 220)
Encapsulate Most Internal APIs(JEP 260)

자바9 핵심 키워드: Reactive Streams CMS가 Deprecated, Default GC는 G1GC, 업데이트 주기 변경


Java 10

* 주요 변경사항

* JVM 관련 변경사항

  • Full GC 병렬처리:
    G1의 Full GC를 병렬화하여 애플리케이션 지연 시간 단축

  • Unified Logging:
    TraceYoungGenTime, TraceOldGenTime flag를 gc+heap+exit flag 하나로 통합

* 기타 변경사항

* 정리

Java9의 안정화 버전이라서 그런지 이렇다할 변경사항은 보이지 않지만 도커 컨테이너에서의 성능 향상을 위한 플래그 추가는 만족스럽다.

기본 GC인 G1GC의 병렬 처리로 변경하였다. GC가 애플리케이션 스레드를 멈추지 않고 병렬로 처리되면 당연히 리소스 사용량이 높아질 수 밖에 없다.
혹시 GC 작동 방식 이 궁금하다면 링크로 이동하여 확인해본다.
필자가 이전에 작성한 GC별 벤치마크 자료 를 확인해보면 확실히 G1GC의 리소스 사용량이 높은 것을 확인할 수 있다.
하드웨어의 성능이 높아지는 추세이다보니 자바에서도 적은 리소스를 사용하는 것보다 할당된 리소스를 충분히 사용하여 빠르게 GC를 수행하는 방향으로 업데이트가 진행되는 것으로 보인다.

javascript와 같이 var 타입이 추가되었다.
문서에 따르면 정확한 타입을 지정하는 것을 개발자들이 불편해하였고, C++, C#, Scala, Go는 이미 데이터 타입을 동적으로 지정하는 것이 가능했다고 얘기하고 있다.
컴파일러가 타입을 효과적으로 지정해주어 개발자들의 편의를 높여준다는 취지인데 이는 추후 업데이트 사항을 지켜보면서 쓸만한 기능인지 확인해봐야 할 듯하다.

Collections final 키워드를 사용해도 내용물이 바뀌는 것을 막을 수 없어서 불편하였는데 Unmodifiable 타입이 추가되어 컬렉션의 내용을 변경하지 못하는 것은 충분히 매력적인 기능이다.

자바10 핵심 키워드: var타입 추가


Java 11

추가 참고: https://openjdk.java.net/projects/jdk/11/

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

* 정리

var를 람다 표현식에서도 사용가능하다. 10버전에 이어 자바도 동적으로 타입이 지정되도록 업데이트 하는 것으로 보인다.

기존에 밀어주던 G1GC의 업데이트 사항은 없고 신규 실험적 GC인 ZGC가 출시되었다.

이번 업데이트에서 가장 많이 언급된 문구는 Date와 Window인 듯하다. (물론 중요한 부분은 아니지만)
Window PC와 Window 서버를 사용하지 않는다면 Window 관련 업데이트는 큰 신경을 쓰지 않아도 될 듯하다.
Date 관련 업데이트도 상당히 많이 있는데 개인적으로 모든 업데이트 사항을 확인할 필요까지는 없으며 Java8에서 추가된 DateTime 패키지를 사용하면 될 듯하다.

혹시라도 Java에서 시간관련 업데이트가 지속적으로 이루어지는 이유가 궁금하다면 Naver D2 기술블로그(링크) 에서 확인해보도록 한다.

자바11 핵심 키워드: 람다에서 var사용 가능, ZGC 실험적 출시


Java 12

추가 참고: https://openjdk.java.net/projects/jdk/12/

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

* 정리

우리가 체감할 수 있을 만한 변경사항은 Switch문의 변경이다. Kotlin과 비슷하게 변경되었다는 점이 주목할 만하다.

JVM 관련 업데이트가 상당히 많이 보인다. Java 11에서 ZGC가 추가된 것에 이어 다음 버전인 Java 12에서 새로운 GC인 Shenandoah GC가 실험적 버전으로 출시되었다.
G1성능 향상을 위한 업데이트가 세 개나 이루어졌다. Oracle에서 G1을 확실히 밀어주고 있는 것으로 보인다.
애플리케이션 스레드와 동기로 작동하는 Parallel GC의 성능 향상 업데이트도 이루어졌다. (동기 GC중 유일하게 Oracle에서 지속적으로 업데이트를 하는 것으로 보인다.)
이번 업데이트로 보아 G1의 차기 GC는 ZGC와 Shenandoah GC 중 하나가 될 가능성이 높아보이는데 추후 업데이트를 보면서 누가 이기는지 지속적으로 확인해보면 좋을 듯하다.

자바12 핵심 키워드: Switch문법 변경, Shenandoah GC 실험적 출시


Java 13

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

* 정리

주요 변경사항은 12버전에 이어 Switch문이 개선되었다. 아직 Preview 버전인 것을 보아 다음 버전까지 지켜보아야한다.
multiline String을 위한 텍스트 블록이 드디어 추가되었다.
ZGC의 성능을 향상시키는 업데이트가 세 개나 진행되었다.

Java13 핵심 키워드: ZGC의 지속적인 성능 향상
(Switch Expression과 Text Blocks는 Preview 버전이기 때문에 핵심 키워드에서는 생략)


Java 14

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

  • Better Listing of Arrays
  • Improved Serialization Handling
  • Turned Off AOT by Default and Changed Related Flags to Experimental

* 정리

가장 큰 체감이 되는 부분은 Kotlin의 Data 클래스와 같은 역할을 하는 Records 클래스가 추가되었다는 점이다. (물론 아직은 Preview)
NPE 상세 메시지를 확인 가능하다는 점도 충분히 매력적인 업데이트처럼 보인다.
(-XX:+ShowCodeDetailsInExceptionMessages의 기본값을 활성화로 해주면 좋았을텐데 비활성화가 기본값이다.)

JVM 관련 업데이트 사항이 매우 많다.

단편화 문제를 해결하지 못한 CMS가 결국 삭제되었다.
ZGC의 성능 향상은 없고 G1GC의 단 하나의 성능 향상 업데이트가 있었다.
Shenandoah GC의 경우 4개의 성능 향상과 1개의 Profiling을 위한 업데이트가 진행되었다.

CMS가 제거되면서 Concurrency하게 작동하는 GC는 G1이 유일해졌고 ZGC와 Shenandoah GC가 빠르게 업데이트 되고 있다.
ZGC와 Shenandoah GC의 경우 아직 Experimental 버전이지만 조만간 정식 버전으로 출시할 가능성이 높아보인다.

자바14 핵심 키워드: CMS GC 제거, ZGC의 지원 범위 확대, Shenandoah GC 위주의 성능 향상
(Records의 경우 Preview이기 때문에 핵심 키워드에서 생략)


Java 15

* 주요 변경사항

* JVM 관련 변경사항

* 기타 변경사항

* 정리

Text Blocks가 정식 출시된 것 이외에 체감될 변경은 없다.
Experimental 버전에서 많은 업데이트가 이루어지던 ZGC가 드디어 정식으로 추가되었다.

Java15 핵심 키워드: Text Blocks 문법의 정식 출시, ZGC 정식 출시, 모니터링 및 디버깅 기능 개선


Java 16

* 주요 변경사항

* JVM 관련 변경사항

  • ZGC Concurrent Stack Processing:
    ZGC가 Thread Stack을 safepoint에서 Concurrency 단계로 이동하여 Stop The World 시간없이 처리하도록 성능 향상.
  • Concurrently Uncommit Memory in G1:
    OS에 메모리를 반납하고 힙을 축소하는 것은 많이 시간이 소요되는데 이러한 작업을 Concurrently하게 처리하여 성능 향상.

* 기타 변경사항

* 정리

Records 클래스가 정식으로 자바 문법에 추가되었다.

확실한 경우 타입 캐스팅없이 객체를 사용할 수 있도록 Pattern Matching 기능이 추가되었다.
다른 언어로 작성된 코드를 호출할 수 있는 기능과 힙 메모리 외부의 메모리에 액세스 할 수 있는 기능이 지속적으로 개발되고 있다.
두 기능 모두 큰 변화처럼 안보일 수 있지만 비슷한 기능들이 Java16에 이어 Java17에도 업데이트가 진행된다.
자바에서 관심을 가지고 업데이트를 하는 만큼 우리도 관심을 가지고 지켜볼 필요가 있다.

Sealed Classes가 두번째 Preview 버전을 출시하였다.

자바16 핵심 키워드: Records 클래스 출시, Pattern Matching


Java 17

* 주요 변경사항

* JVM 변경 사항

* 기타 변경사항

* 정리

오라클에서 자바의 라이선스를 OTN에서 NFTC로 변경하였다.
NFTC(Oracle No-Fee Terms and Conditions)의 경우 OTN과 다르게 사용 용도 및 배포에 있어 제약 조건이 있던 OTN 라이선스와는 다르다.
상업 및 프로덕션 용도를 포함하여 모든 사용자들에게 무료로 사용 및 배포를 허용한다.

Sealed Classes가 정식적으로 자바 문법에 추가되었다.

Java16에 이어 switch 문에서 Pattern Matching을 통해 타입 캐스팅 없이 객체를 사용할 수 있도록 Preview 버전이 출시되었다.

자바17 핵심 키워드: 라이선스의 변경, Sealed Classes, Pattern Matching


간단 정리

지금까지 자바8에서 자바17까지 업데이트 사항에 대해서 알아보았다.
정리하고 보니 생각보다 너무 많은 양을 작성하게 된 듯하다.
평소에 잊지 않도록 주기적으로 정리하고 인터뷰 전에 주요 변경사항과 핵심 키워드 정도만 읽고 들어가도 충분할 듯 하다.


참고자료

용어정리

  • LTS(Long Term Support): 장기 지원 버전으로 일반적인 경우보다 장기간에 걸쳐 지원하도록 특별히 고안된 소프트웨어의 버전.

'Java' 카테고리의 다른 글

[Java] 버전별 업데이트 사항(보안)  (0) 2022.04.19