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

重磅:JDK 11 正式發佈!東半球第二全特性解讀!

點擊上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 

來源:https://mp.weixin.qq.com/s/Yz8V3inWN8uErKM-IdMFWQ

千呼萬喚,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運算式如下:

(xy-x.process(y)

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

var foo = new Foo();
for (var foo : foos) { ... }
try (var foo = ...) { ... } catch ...

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

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

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

@Nonnull var x = new Foo();
(@Nonnull var x, @Nullable var y) -> x.process(y)

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運算式如下:

(xy-x.process(y)

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

var foo = new Foo();
for (var foo : foos) { ... }
try (var foo = ...) { ... } catch ...

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

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

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

@Nonnull var x = new Foo();
(@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,示例代碼如下:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)
// alternatively: kpg = KeyPairGenerator.getInstance("X25519")
KeyPair kp = kpg.generateKeyPair();

KeyFactory kf = KeyFactory.getInstance("XDH");
BigInteger u = ...
XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);

KeyAgreement ka = KeyAgreement.getInstance("XDH");
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
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啟動器能直接運行這個原始碼級的程式:

java HelloWorld.java

等價於:

javac -d  HelloWorld.java
java -cp  helloWorld
java Factorial.java 3 4 5

等價於:

javac -d  Factorial.java
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停頓時間比較:

ZGC
                avg: 1.091ms (+/-0.215ms)
    95th percentile: 1.380ms
    99th percentile: 1.512ms
  99.9th percentile: 1.663ms
 99.99th percentile: 1.681ms
                max1.681ms

G1
                avg: 156.806ms (+/-71.126ms)
    95th percentile: 316.672ms
    99th percentile: 428.095ms
  99.9th percentile: 543.846ms
 99.99th percentile: 543.846ms
                max543.846ms

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

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



如果你對 Dubbo / Netty 等等原始碼與原理感興趣,歡迎加入我的知識星球一起交流。長按下方二維碼噢

目前在知識星球更新了《Dubbo 原始碼解析》目錄如下:

01. 除錯環境搭建
02. 專案結構一覽
03. 配置 Configuration
04. 核心流程一覽

05. 拓展機制 SPI

06. 執行緒池

07. 服務暴露 Export

08. 服務取用 Refer

09. 註冊中心 Registry

10. 動態編譯 Compile

11. 動態代理 Proxy

12. 服務呼叫 Invoke

13. 呼叫特性 

14. 過濾器 Filter

15. NIO 服務器

16. P2P 服務器

17. HTTP 服務器

18. 序列化 Serialization

19. 集群容錯 Cluster

20. 優雅停機

21. 日誌適配

22. 狀態檢查

23. 監控中心 Monitor

24. 管理中心 Admin

25. 運維命令 QOS

26. 鏈路追蹤 Tracing

… 一共 69+ 篇

目前在知識星球更新了《Netty 原始碼解析》目錄如下:

01. 除錯環境搭建
02. NIO 基礎
03. Netty 簡介
04. 啟動 Bootstrap

05. 事件輪詢 EventLoop

06. 通道管道 ChannelPipeline

07. 通道 Channel

08. 位元組緩衝區 ByteBuf

09. 通道處理器 ChannelHandler

10. 編解碼 Codec

11. 工具類 Util

… 一共 61+ 篇

目前在知識星球更新了《資料庫物體設計》目錄如下:


01. 商品模塊
02. 交易模塊
03. 營銷模塊
04. 公用模塊

… 一共 17+ 篇

赞(0)

分享創造快樂