公司在用JDK11,都有什么區別?
不得不說,現在雖然大部分公司還是在使用的 JDK8,但是也有一些相對比較小的公司,會跟風,直接切換版本,畢竟這個項目切換版本,其實還是一個很大的問題,一般的大公司的話,可能并沒有那么容易起的去切換版本,反而是小公司更容易去使用新技術,盡管可能有些問題解決不了,就像當初瘋狂擴散的微服務,但是卻不處理分布式所帶來的事務問題一樣,今天我們就來看看這個JDK11 給我們帶來了哪些改變。
JDK11
關于 JDK11 的安裝的話,了不起就壓根不用說了,因為 JDK 的安裝和配置,基本一樣,但是從 JDK 10 開始,我裝完之后,自動把 path 就給我配置了,所以,感覺更加的簡單和方便了,我們看看 JDK11 中都增加加了哪些內容,不管實用不實用,我們知道有這個內容,那就給自己了印象,就沒問題。
String
String 增加了一些 API,這些 API 也都是挺好用的內容,我們來看一下
//判斷字符串是否都是空
String str = "abc";
System.out.println(str.isBlank());
//去除字符串收尾空白
System.out.println(str.strip());
System.out.println(str.trim());
//去除首部的字符串空格
System.out.println(str.stripLeading());
//去除尾部的字符串空格
System.out.println(str.stripTrailing());
//復制字符串,復制多少次由repeat的參數決定
String str2 = "abc";
String repeat = str2.repeat(3);
System.out.println(repeat);
//統一字符串行數,沒啥用
long count = str2.lines().count();
System.out.println(count);
至少目前來看,有幾個方法是有點用的,但是也有沒太大作用的,比如那個統一行數還有就是復制的,用的情況還真的不是太多的樣子。
HttpClient
//異步請求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("http://baidu.com/")).build();
HttpResponse.BodyHandler<String> stringBodyHandler = HttpResponse.BodyHandlers.ofString();
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, stringBodyHandler);
HttpResponse<String> response = future.get();
// 返回結果
String body = response.body();
// 同步請求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("http://baidu.com/")).build();
HttpResponse.BodyHandler<String> stringBodyHandler = HttpResponse.BodyHandlers.ofString();
HttpResponse<String> send = client.send(request, stringBodyHandler);
String body = send.body();
實際上在 JDK10 就已經出現了,只不過在 JDK11 中又做了優化,目前版本已經支持HTTP1.1、HTTP2、websocket等常用的基于http的協議,并支持了了同步、異步、響應式等交互方式。當前版本的實現還是比較簡單,沒有對于常用restful、content-type的封裝支持。
刪除 Java EE 和 CORBA 模塊
由于EJB方案的繁瑣和低效率一直以來備受詬病,而當EJB方案在與Spring分道揚鑣之后,EJB方案全面衰落。這在如今我們在一些Spring書籍中還有對于一些EJB的描述。
EJB在我來看是希望能從標準方面制定一款大而全的產品,但實際上全面的覆蓋帶來的是,繁瑣的規則,冗余的代碼,難以遵守的設計規范。
因此從廠商來說,支持EJB就需要付出巨大的生產成本,更不要說正式投入生產環境。事實上Spring正式由于理念上與EJB的不同,采用了輕快小的方案,贏得了眾多用戶的支持。
并且從歷史來看,復雜的設計意味著高昂的學習成本,生產成本,維護成本,Spring憑借此贏得了與EJB的競爭,但在Spring 3以后迅速的發展讓Spring加入了眾多的細化組件,此時Spring慢慢變得更為復雜。
在后續SpringBoot誕生,極大的簡化了Spring的配置以及對于Spring眾多組件的管理。這一點來看輕快小又是一次歷史的選擇了。
ZGC的改變
從JDK 8開始,JDK使用G1作為默認的垃圾回收器。G1可以說是GC的一個里程碑,G1之前的GC回收,還是基于固定的內存區域,而G1采用了一種“細粒度”的內存管理策略,不在固定的區分內存區域屬于surviors、eden、old,而我們不需要再去對于年輕代使用一種回收策略,老年代使用一種回收策略,取而代之的是一種整體的內存回收策略。
這種回收策略在我們當下cpu、內存、服務規模都越來越大的情況下提供了更好的表現。 而這一代ZGC更是有了突破性的進步,SPECjbb 2015基準測試,在128G的大堆下
//數值越高越好
ZGC
max-jOPS: 100%
critical-jOPS: 76.1%
G1
max-jOPS: 91.2%
critical-jOPS: 54.7%
//數值越低越好
ZGC
avg: 1.091ms (+/-0.215ms)
95th percentile: 1.380ms
99th percentile: 1.512ms
99.9th percentile: 1.663ms
99.99th percentile: 1.681ms
max: 1.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
max: 543.846ms
從原理上來理解,ZGC可以看做是G1之上更細粒度的內存管理策略。由于內存的不斷分配回收會產生大量的內存碎片空間,因此需要整理策略防止內存空間碎片化,在整理期間需要將對于內存引用的線程邏輯暫停,這個過程被稱為"Stop the world"。只有當整理完成后,線程邏輯才可以繼續運行。 一般而言,主要有如下幾種方式優化"Stop the world"
- 使用多個線程同時回收(并行回收)
- 回收過程分為多次停頓(增量回收)
- 在程序運行期間回收,不需要停頓或只停頓很短時間(并發回收)
- 只回收內存而不整理內存
ZGC主要采用的是并發回收的策略,相較于G1 ZGC最主要的提升是使用Load Barrier技術實現,引用R大對于ZGC的評價.
對于Region的更細粒度控制,不同與G1的固定region,ZGC可以有多個size的RegionNuma架構的支持。
其實這個 ZGC 對我們開發來說是無感的操作,我們知道有這么回事就行。
關于 JDK11 的新特性,你還了解多少?