JDK12新特性詳解

xz43發表於2020-01-20

1、JDK12之Shenandoah低暫停時間垃圾收集器(實驗性)

       定義:

    新增一個名為Shenandoah的新垃圾收集(GC)演算法,透過與正在執行的Java執行緒同時進行疏散工作
來減少GC暫停時間。使用Shenandoah的暫停時間與堆大小無關,這意味著無論堆是200MB還是200GB,都
將具有相同的一致暫停時間。

       非目標:

    這不是一個統治所有人的GC。還有其他垃圾收集演算法可以優先考慮吞吐量或記憶體佔用而不是響應性。
Shenandoah是適用於評估響應性和可預測的短暫停頓的應用程式的演算法。目標不是解決所有JVM暫停問
題。由於GC之外的其他原因(例如安全時間點(TTSP)釋出或監控通脹)而暫停時間超出了此JEP的範圍。

       構建和呼叫:

    作為實驗性功能,Shenandoah將-XX:+UnlockExperimentalVMOptions在命令列中要求。Shenandoah構建系統會自動禁用不受
支援的配置。下游建設者可以選擇--with-jvm-features=-shenandoahgc在其他支援的平臺上禁用構建Shenandoah。
要啟用/使用Shenandoah GC,需要以下JVM選項:-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

2、JDK12之Microbenchmark Suite

       定義:

    在JDK原始碼中新增一套基本的微基準測試,使開發人員可以輕鬆執行現有的微基準測試並創
建新的基準測試。

       目標:

1、基於[Java Microbenchmark線束(JMH)] [1]
2、穩定且經過調整的基準測試,針對持續效能測試
    2.1、在功能釋出的功能完成里程碑之後,以及非功能版本之後的穩定且不移動的套件
    2.2、支援與先前JDK版本的適用測試比較
3、簡單
    3.1 輕鬆新增新基準
    3.2 在API和選項更改,不推薦使用或在開發期間刪除時,可以輕鬆更新測試
    3.3 易於構建
    3.4 易於查詢和執行基準
    3.5 支援JMH更新
    3.6 在套件中包含大約一百個基準的初始集

3、JDK12之Switch表示式(預覽版)

      預覽功能,如果該jdk12的switch效果不好的話,會被下一版本jdk13直接移除該功能,並不是之後每個版本必須的。

       許多break使它不必要地冗長,如果忘記寫break,則會產生意料之外的結果或者異常,所以針對於此jdk12在這裡進行了最佳化升級。

       JDK12之前的版本:   

switch (day) {    case MONDAY:    case FRIDAY:    case SUNDAY:        System.out.println(6);        break;    case TUESDAY:        System.out.println(7);        break;    case THURSDAY:    case SATURDAY:        System.out.println(8);        break;    case WEDNESDAY:        System.out.println(9);        break;
}

       JDK12:我們建議引入一種新形式的開關標籤,寫成“case L ->”表示如果標籤匹配,則只執行標籤右側的程式碼。

switch (day) {    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);    case TUESDAY                -> System.out.println(7);    case THURSDAY, SATURDAY     -> System.out.println(8);    case WEDNESDAY              -> System.out.println(9);
}

       許多Switch表示式,每個case都會賦值給一個變數或者執行某種操作,如下是賦值給numLetters變數具體值。

       JDK12之前:

int numLetters;switch (day) {    case MONDAY:    case FRIDAY:    case SUNDAY:
        numLetters = 6;        break;    case TUESDAY:
        numLetters = 7;        break;    case THURSDAY:    case SATURDAY:
        numLetters = 8;        break;    case WEDNESDAY:
        numLetters = 9;        break;    default:        throw new IllegalStateException("Wat: " + day);
}

       JDK12:將此表達為一種陳述是迂迴的,重複的,並且容易出錯。意味著我們應該計算numLetters每一天的價值。應該可以直接說,使用更清晰,更安全Switch表示式

int numLetters = switch (day) {    case MONDAY, FRIDAY, SUNDAY -> 6;    case TUESDAY                -> 7;    case THURSDAY, SATURDAY     -> 8;    case WEDNESDAY              -> 9;
};

       如果將它用在方法上,則可以為:

static void howMany(int k) {    switch (k) {        case 1 -> System.out.println("one");        case 2 -> System.out.println("two");        case 3 -> System.out.println("many");
    }
}

       或者類上,我想到的這個switch這個功能可以用在抽象工廠類方面。

T result = switch (arg) {
    case L1 -> e1;
    case L2 -> e2;
    default -> e3;};

4、JDK12之JVM常量API

       摘要:

引入API來模擬關鍵類檔案和執行時工件的名義描述,特別是可從常量池載入的常量。

       動機:

    每個Java類檔案都有一個常量池,用於儲存類中位元組碼指令的運算元。從廣義上講,常量池中的條目描述了執行
時工件(如類和方法)或簡單值(如字串和整數)。所有這些條目都稱為可載入常量,因為它們可以作為ldc指令的
運算元(“載入常量”)。
它們也可能出現在invokedynamic指令的bootstrap方法的靜態引數列表中。執行一個ldc或invokedynamic指令
導致載入常數被解析成一個標準的Java類,如“活”的值Class,String或int。
    操作class檔案的程式需要對位元組碼指令進行建模,並依次對可載入的常量進行建模。但是,使用標準Java型別
來模擬可載入常量是不合適的。
    描述字串(CONSTANT_String_info條目)的可載入常量可能是可以接受的,因為生成“實時” String物件
很簡單,但是對於描述類(CONSTANT_Class_info條目)的可載入常量是有問題的,因為產生“實時”ClassObject
依賴於類載入的正確性和一致性。
    不幸的是,類載入有許多環境依賴和失敗模式:所需的類不存在或者請求者可能無法訪問; 類載入的結果因上下文
而異; 裝載類有副作用;有時類載入可能根本不可能(例如當所描述的類尚不存在或者無法載入時,如在編譯那些相同類
或在jlink轉換期間)。
    因此,處理可載入常量的程式如果能夠以純粹的名義符號形式操作類和方法,以及不太知名的工件(如方法控制程式碼和動
態計算常量),則會更簡單:    1、位元組碼解析和生成庫必須以符號形式描述類和方法控制程式碼。如果沒有標準機制,它們必須採用ad-hoc機制,無論是
ASM的描述符型別Handle,還是字串元組(方法所有者,方法名稱,方法描述符),或者這些機制的特殊(並且容易出
錯)編碼單個字串。
    2、如果它們可以在符號域中工作而不是使用“實時”類和方法控制程式碼,invokedynamic那麼透過旋轉位元組碼(例如LambdaMetafactory)來操作的Bootstraps 將更簡單。
    3、編譯器和離線轉換器(例如jlink外掛)需要描述無法載入到正在執行的VM的類的類和成員。編譯器外掛(例如注
釋處理器)同樣需要用符號術語來描述程式元素。

5、JDK12之一個AArch64埠,而不是兩個

       摘要:

arm64在保留32位ARM埠和64位aarch64埠的同時,刪除與埠相關的所有源。

       動機:

刪除此埠將允許所有貢獻者將他們的精力集中在單個64位ARM實現上,並消除維護兩個埠所需的重複工作。

6、JDK12之預設CDS檔案

       摘要:

在64位平臺上使用預設類列表增強JDK構建過程以生成類資料共享(CDS)歸檔。

       目標:

1、改善開箱即用的啟動時間
2、消除使用者執行-Xshare:dump以從CDS中受益的需要

7、JDK12之G1的可流動混合收集

       摘要:

如果G1混合集合可能超過暫停目標,則使其可以中止。

       動機:

    G1的目標之一是滿足使用者提供的暫停時間目標以暫停其收集暫停。G1使用高階分析引擎來選擇在集合期間
要完成的工作量(這部分基於應用程式行為)。此選擇的結果是一組稱為集合集的區域。一旦確定了集合集並且
已經開始集合,則G1必須在不停止的情況下收集集合集的所有區域中的所有活動物件。如果啟發式選擇過大的收
集,則此行為可導致G1超過暫停時間目標,例如,如果應用程式的行為發生變化,以致啟發式工作在“陳舊”資料
上,則可能發生這種情況。特別是在混合集合期間可以觀察到這種情況,其中集合集通常可以包含太多舊區域。
需要一種機制來檢測啟發式方法何時反覆為集合選擇錯誤的工作量,如果是,則讓G1逐步遞增地執行收集工作,
其中集合可以在每個步驟之後中止。這種機制將允許G1更頻繁地滿足暫停時間目標。

8、JDK12之從G1中立即返回未使用的已提交記憶體

       摘要:

增強G1垃圾收集器,以便在空閒時自動將Java堆記憶體返回給作業系統。

       成功指標:

如果應用程式活動非常低,G1應該在合理的時間段內釋放未使用的Java堆記憶體。

       動機:

    目前G1垃圾收集器可能無法及時將已提交的Java堆記憶體返回給作業系統。G1僅在完整GC或併發週期內
從Java堆返回記憶體。由於G1很難完全避免完整的GC,並且只觸發基於Java堆佔用和分配活動的併發週期,
因此在許多情況下它不會返回Java堆記憶體,除非在外部強制執行此操作。
    在使用資源支付的容器環境中,這種行為特別不利。即使在VM由於不活動而僅使用其分配的記憶體資源的
一小部分的階段,G1也將保留所有Java堆。這導致客戶始終為所有資源付費,雲提供商無法充分利用其硬體。
    如果VM能夠檢測到Java堆的利用率不足(“空閒”階段),並在此期間自動減少其堆使用量,則兩者都
將受益。
    Shenandoah和OpenJ9的GenCon收集器已經提供了類似的功能。

9、核心庫java.lang中 支援Unicode11

    JDK 12版本包括對Unicode 11.0.0的支援。在釋出支援Unicode 10.0.0的JDK 11之後,Unicode 11.0.0引入了以下JDK 12中包含的新功能:

1、684個新角色
    1.1、66個表情符號字元
    1.2、Copyleft符號
    1.3、評級系統的半星
    1.4、額外的占星符號
    1.5、象棋中國象棋符號
2、11個新區塊
    2.1、喬治亞擴充套件
    2.2、瑪雅數字
    2.3、印度Siyaq數字
    2.4、國際象棋符號
3、7個新指令碼
    3.1、Hanifi Rohingya
    3.2、Old Sogdian
    3.3、Sogdian
    3.4、Dogra
    3.5、Gunjala Gondi
    3.6、Makasar
    3.7、Medefaidrin

10、核心庫java.text支援壓縮數字格式

    NumberFormat新增了對以緊湊形式格式化數字的支援。緊湊數字格式是指以簡短或人類可
讀形式表示的數字。例如,在en_US語言環境中,1000可以格式化為“1K”,1000000可以格式化
為“1M”,具體取決於指定的樣式NumberFormat.Style。緊湊數字格式由LDML的Compact Number格式規範定義。要獲取例項,請使用NumberFormat緊湊數字格式所給出的工廠方法之一。    例如:NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);String result = fmt.format(1000);     上面的例子導致“1K”。

12、安全庫java.security

       禁止並允許java.security.manager系統屬性的選項 

    新的“disallow”和“allow”令牌選項已新增到java.security.manager系統屬性中。
在JDK實現中,如果Java虛擬機器以系統屬性java.security.manager設定為“disallow”開始,
則該System.setSecurityManager方法不能用於設定安全管理器並將丟擲
UnsupportedOperationException。“disallow”選項可以提高從未設定安全管理器的應用程
序的執行時效能。

       groupname選項新增到keytool金鑰對生成 

-groupname新增了一個新選項,keytool -genkeypair以便使用者在生成金鑰對時可以指
定命名組。例如,keytool -genkeypair -keyalg EC -groupname secp384r1將使用
secp384r1曲線生成EC金鑰對。由於可能存在多個具有相同大小的曲線,因此使用該-groupname
選項優先於該-keysize選項。

       新Java飛行記錄器(JFR)安全事件

略過...

       自定義PKCS12金鑰庫生成 

    新增了新的系統和安全屬性,使使用者能夠自定義PKCS#12金鑰庫的生成。這包括用於金鑰保護,
證照保護和MacData的演算法和引數。可以在檔案的“PKCS12 KeyStore屬性”部分中找到這些屬性的
詳細說明和可能的值java.security。

13、安全庫javax.net.ssl

       ChaCha20和Poly1305 TLS密碼

    JSSE中新增了使用ChaCha20-Poly1305演算法的新TLS密碼套件。預設情況下啟用這些密碼套件。
TLS_CHACHA20_POLY1305_SHA256密碼套件適用於TLS 1.3。

14、安全庫/ org.ietf.jgss

       在krb5.conf中支援dns_canonicalize_hostname

    該dns_canonicalize_hostname標誌中krb5.conf的配置檔案現在是由JDK Kerberos實現支援。
設定為“true”時,服務主體名稱中的短主機名將被規範化為完全限定的域名(如果可用)。否則,不執行規
範化。預設值是true”。這也是JDK 12之前的行為。

15、刪除項

       核心庫/ java.util.jar中,刪除java.util.ZipFile / Inflator / Deflator中的finalize方法 

    該finalize方法在java.util.ZipFile,java.util.Inflator和java.util.Deflator是在JDK9
棄用用於移除及其執行了更新,是一個空操作。該finalize在方法java.util.ZipFile,java.util.Inflator
以及java.util.Deflator在此版本中被刪除。finalize應修改為執行清理而重寫的子類,以使用備用清理機制並
刪除寫finalize方法。
    finalize方法,去除將暴露Object.finalize到的子類ZipFile,Deflater和Inflater。finalize由於
宣告的異常發生更改,可能會在覆蓋時發生編譯錯誤。Object.finalize現在宣佈投擲java.lang.Throwable。
以前,只有java.io.IOException宣佈。

       核心庫/ java.io,從FileInputStream和FileOutputStream中刪除finalize方法 

    該finalize方法FileInputStream和FileOutputStream被棄用去除JDK 9.他們已經在此版本中被刪除。
所述java.lang.ref.Cleaner,自JDK9的主要機制已被實施,以關閉檔案描述符不再從可到達的FileInputStream和FileOutputStream。關閉檔案的推薦方法是顯式呼叫close或使用try-with-resources。

       工具/ javac的刪除javac支援6 / 1.6源,目標和釋出值 

為的javac的6/1.6的引數值的支援-source,-target以及--release標誌已被刪除。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9399028/viewspace-2674131/,如需轉載,請註明出處,否則將追究法律責任。

相關文章