歡迎光臨
每天分享高質量文章

重磅:JDK11正式發佈!史上最全特性完整解讀!

點擊上方“Java技術驛站”,選擇“置頂公眾號”。

有內涵、有價值的文章第一時間送達!

精品專欄

 

千呼萬喚,JDK11 於 2018-09-25 正式發佈!你是不是和筆者一樣還在使用JDK8 呢?甚至有些開發者還在使用 JDK7!沒關係,讓我們先一睹 JDK11 的風采。

JDK11發佈計劃

  • 2018/06/28        Rampdown Phase One (fork from main line)

  • 2018/07/19        All Tests Run

  • 2018/07/26        Rampdown Phase Two

  • 2018/08/16        Initial Release Candidate

  • 2018/08/30        Final Release Candidate

  • 2018/09/25        General Availability

說明:GA即General Availability,也就是官方推薦可以廣泛使用的版本。

JDK11特性一覽

  • 181: Nest-Based Access Control

  • 309: Dynamic Class-File Constants

  • 315: Improve Aarch64 Intrinsics

  • 318: Epsilon: A No-Op Garbage Collector

  • 320: Remove the Java EE and CORBA Modules

  • 321: HTTP Client (Standard)

  • 323: Local-Variable Syntax for Lambda Parameters

  • 324: Key Agreement with Curve25519 and Curve448

  • 327: Unicode 10

  • 328: Flight Recorder

  • 329: ChaCha20 and Poly1305 Cryptographic Algorithms

  • 330: Launch Single-File Source-Code Programs

  • 331: Low-Overhead Heap Profiling

  • 332: Transport Layer Security (TLS) 1.3

  • 333: ZGC: A Scalable Low-Latency Garbage Collector    (Experimental)

  • 335: Deprecate the Nashorn JavaScript Engine

  • 336: Deprecate the Pack200 Tools and API

特性詳解

接下來對每個特性進行詳細解讀。

JEP 318: Epsilon: A No-Op Garbage Collector

JDK 上對這個特性的描述是:開發一個處理記憶體分配但不實現任何實際記憶體回收機制的 GC,一旦可用堆記憶體用完,JVM 就會退出。

如果有 System.gc() 的呼叫,實際上什麼也不會發生(這種場景下和 -XX:+DisableExplicitGC 效果一樣),因為沒有記憶體回收,這個實現可能會警告用戶嘗試強制 GC 是徒勞。

用法非常簡單: -XX:+UseEpsilonGC


動機

提供完全被動的 GC 實現,具有有限的分配限制和盡可能低的延遲開銷,但代價是記憶體占用和記憶體吞吐量。

眾所周知,Java 實現可廣泛選擇高度可配置的 GC 實現。 各種可用的收集器最終滿足不同的需求,即使它們的可配置性使它們的功能相交。 有時更容易維護單獨的實現,而不是在現有 GC 實現上堆積另一個配置選項。

它的主要用途如下:

  • 性能測試(它可以幫助過濾掉GC引起的性能假象);

  • 記憶體壓力測試(例如,知道測試用例應該分配不超過 1 GB 的記憶體,我們可以使用 -Xmx1g 配置 -XX:+UseEpsilonGC ,如果違反了該約束,則會 heap dump 並崩潰);

  • 非常短的 JOB 任務(對於這種任務,接受 GC 清理堆那都是浪費空間);

  • VM接口測試;

  • Last-drop 延遲&吞吐改進;

JEP 320: Remove the Java EE and CORBA Modules

Java EE 和 CORBA 兩個模塊在 JDK9 中已經標記”deprecated“,在JDK11 中正式移除。JDK 中 deprecated 的意思是在不建議使用,在未來的 release 版本會被刪除。


動機

JavaEE 由 4 部分組成:

  • JAX-WS (Java API for XML-Based Web Services),

  • JAXB (Java Architecture for XML Binding)

  • JAF (the JavaBeans Activation Framework)

  • Common Annotations.

但是這個特性和 JavaSE 關係不大。並且 JavaEE 被維護在 Github(https://github.com/javaee)中,版本同步造成維護困難。最後,JavaEE 可以單獨取用,maven 中心倉庫也提供了 JavaEE(http://mvnrepository.com/artifact/javax/javaee-api/8.0),所以沒必要把 JavaEE 包含到 JavaSE 中。

至於 CORBA ,使用 Java 中的 CORBA 開發程式沒有太大的興趣。因此,在JavaEE 就把 CORBA 標記為 “Proposed Optional” ,這就表明將來可能會放棄對這些技術的必要支持。

JEP 321: HTTP Client (Standard)

將 JDK9 引進並孵化的 HTTP 客戶端 API 作為標準,即 HTTP/2 Client。它定義了一個全新的實現了 HTTP/2 和 WebSocket 的 HTTP 客戶端 API,並且可以取代 HttpURLConnection。


動機

已經存在的 HttpURLConnection 有如下問題:

  • 在設計時考慮了多種協議,但是現在幾乎所有協議現已不存在。

  • API 早於 HTTP/1.1 並且太抽象;

  • 使用很不友好;

  • 只能以阻塞樣式工作;

  • 非常難維護;

JEP 323: Local-Variable Syntax for Lambda Parameters

在宣告隱式型別的lambda運算式的形參時允許使用var。


動機

lamdba 運算式可能是隱式型別的,它形參的所有型別全部靠推到出來的。隱式型別 lambda 運算式如下:

  1. (x, y) -> x.process(y)

Java SE 10讓隱式型別變數可用於本地變數:

  1. var foo = new Foo();

  2. for (var foo : foos) { ... }

  3. try (var foo = ...) { ... } catch ...

為了和本地變數保持一致,我們希望允許 var 作為隱式型別 lambda 運算式的形參:

  1. (var x, var y) -> x.process(y)

統一格式的一個好處就是 modifiers 和 notably 註解能被加在本地變數和 lambda 運算式的形參上,並且不會丟失簡潔性:

  1. @Nonnull var x = new Foo();

  2. (@Nonnull var x, @Nullable var y) -> x.process(y)

JEP 324: Key Agreement with Curve25519 and Curve448

用 RFC 7748 中描述到的 Curve25519 和 Curve448 實現秘鑰協議。 RFC 7748 定義的秘鑰協商方案更高效,更安全。這個 JEP 的主要標的就是為這個標準定義 API 和實現。


動機

密碼學要求使用 Curve25519 和 Curve448 是因為它們的安全性和性能。JDK 會增加兩個新的接口 XECPublicKey 和 XECPrivateKey,示例代碼如下:

  1. KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");

  2. NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");

  3. kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)

  4. // alternatively: kpg = KeyPairGenerator.getInstance("X25519")

  5. KeyPair kp = kpg.generateKeyPair();

  6. KeyFactory kf = KeyFactory.getInstance("XDH");

  7. BigInteger u = ...

  8. XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);

  9. PublicKey pubKey = kf.generatePublic(pubSpec);

  10. KeyAgreement ka = KeyAgreement.getInstance("XDH");

  11. ka.init(kp.getPrivate());

  12. ka.doPhase(pubKey, true);

  13. byte[] secret = ka.generateSecret();

JEP 327: Unicode 10

更新平臺 API 支持 Unicode 10.0版本(Unicode 10.0 概述:Unicode 10.0 增加了 8518 個字符, 總計達到了 136,690 個字符. 並且增加了 4 個腳本, 總結 139 個腳本, 同時還有 56 個新的 emoji 表情符號。參考:http://unicode.org/versions/Unicode10.0.0/)。


動機

Unicode 是一個不斷進化的工業標準,因此必須不斷保持 Java 和 Unicode 最新版本同步。

JEP 328: Flight Recorder

提供一個低開銷的,為了排錯Java應用問題,以及JVM問題的資料收集框架,希望達到的標的如下:

  • 提供用於生產和消費資料作為事件的API;

  • 提供快取機制和二進制資料格式;

  • 允許事件配置和事件過濾;

  • 提供OS,JVM和JDK庫的事件;


動機

排錯,監控,性能分析是整個開發生命周期必不可少的一部分,但是某些問題只會在大量真實資料壓力下才會發生在生產環境。

Flight Recorder記錄源自應用程式,JVM和OS的事件。 事件儲存在一個檔案中,該檔案可以附加到錯誤報告中並由支持工程師進行檢查,允許事後分析導致問題的時期內的問題。工具可以使用API從記錄檔案中提取信息。

多說一句:Flight Recorder的名字來源有點像來自於飛機的黑盒子,一種用來記錄飛機飛行情況的的儀器。而Flight Recorder就是記錄Java程式運行情況的工具。

JEP 329: ChaCha20 and Poly1305 Cryptographic Algorithms

實現RFC 7539中指定的 ChaCha20 和 ChaCha20-Poly1305 兩種加密演算法。


動機

唯一一個其他廣泛採用的RC4長期以來一直被認為是不安全的,業界一致認為當下ChaCha20-Poly1305是安全的。

JEP 330: Launch Single-File Source-Code Programs

增強Java啟動器支持運行單個Java原始碼檔案的程式。


動機

單檔案程式是指整個程式只有一個原始碼檔案,通常是早期學習Java階段,或者寫一個小型工具類。以HelloWorld.java為例,運行它之前需要先編譯。我們希望Java啟動器能直接運行這個原始碼級的程式:

  1. java HelloWorld.java

等價於:

  1. javac -d  HelloWorld.java

  2. java -cp  helloWorld class="">java Factorial.java 3 4 5

等價於:

  1. javac -d  Factorial.java

  2. java -cp  Factorial 3 4 5

到JDK10為止,Java啟動器能以三種方式運行:

  1. 啟動一個class檔案;

  2. 啟動一個JAR中的main方法類;

  3. 啟動一個模塊中的main方法類;

JDK11再加一個,即第四種方式:啟動一個源檔案申明的類。

JEP 331: Low-Overhead Heap Profiling

提供一種低開銷的Java堆分配採樣方法,得到堆分配的Java物件信息,可通過JVMTI訪問。希望達到的標的如下:

  • 足夠低的開銷,可以預設且一直開啟;

  • 能通過定義好的程式接口訪問;

  • 能採樣所有分配;

  • 能給出生存和死亡的Java物件信息;


動機

對用戶來說,瞭解它們堆里的記憶體是很重要的需求。目前有一些已經開發的工具,允許用戶窺探它們的堆,比如:Java Flight Recorder, jmap, YourKit, 以及VisualVM tools.。但是這工具都有一個很大的缺點:無法得到物件的分配位置。headp dump以及heap histo都沒有這個信息,但是這個信息對於除錯記憶體問題至關重要。因為它能告訴開發者,他們的代碼發生(尤其是壞的)分配的確切位置。

JEP 332: Transport Layer Security (TLS) 1.3

實現TLS協議1.3版本。(TLS允許客戶端和服務端通過互聯網以一種防止竊聽,篡改以及訊息偽造的方式進行通信)。


動機

TLS 1.3是TLS協議的重大改進,與以前的版本相比,它提供了顯著的安全性和性能改進。其他供應商的幾個早期實現已經可用。我們需要支持TLS 1.3以保持競爭力並與最新標準保持同步。這個特性的實現動機和Unicode 10一樣,也是緊跟歷史潮流。

JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)

ZGC:這應該是JDK11最為矚目的特性,沒有之一。但是後面帶了Experimental,說明還不建議用到生產環境。看看官方對這個特性的標的描述:

  • GC暫停時間不會超過10ms;

  • 即能處理幾百兆小堆,也能處理幾個T的大堆(OMG);

  • 和G1相比,應用吞吐能力不會下降超過15%;

  • 為未來的GC功能和利用colord指標以及Load barriers優化奠定基礎;

  • 初始只支持64位系統;


動機

GC是Java主要優勢之一。然而,當GC停頓太長,就會開始影響應用的響應時間。消除或者減少GC停頓時長,Java將對更廣泛的應用場景是一個更有吸引力的平臺。此外,現代系統中可用記憶體不斷增長, 用戶和程式員希望JVM能夠以高效的方式充分利用這些記憶體,並且無需長時間的GC暫停時間。

ZGC一個併發,基於region,壓縮型的垃圾收集器,只有root掃描階段會STW,因此GC停頓時間不會隨著堆的增長和存活物件的增長而變長。

ZGC和G1停頓時間比較:

  1. ZGC

  2.                 avg: 1.091ms (+/-0.215ms)

  3.     95th percentile: 1.380ms

  4.     99th percentile: 1.512ms

  5.   99.9th percentile: 1.663ms

  6.  99.99th percentile: 1.681ms

  7.                 max: 1.681ms

  8. G1

  9.                 avg: 156.806ms (+/-71.126ms)

  10.     95th percentile: 316.672ms

  11.     99th percentile: 428.095ms

  12.   99.9th percentile: 543.846ms

  13.  99.99th percentile: 543.846ms

  14.                 max: 543.846ms

用法: -XX:+UnlockExperimentalVMOptions-XX:+UseZGC,因為ZGC還處於實驗階段,所以需要通過JVM引數UnlockExperimentalVMOptions 來解鎖這個特性。

參考:http://openjdk.java.net/projects/jdk/11/

END

我是 Java 技術驛站,感謝有你

赞(0)

分享創造快樂

© 2021 知識星球   网站地图