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