<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      2017年8月,JCP執(zhí)行委員會提出將Java的發(fā)布頻率改為每六個月一次,新的發(fā)布周期嚴(yán)格遵循時間點,將在每年的3月份和9月份發(fā)布。

      目前,JDK官網(wǎng)上已經(jīng)可以看到JDK 13的進(jìn)展,最新版的JDK 13將于2019年9月17日發(fā)布。



      目前,JDK13處于Release-Candidate
      Phase(發(fā)布候選階段),將于9月17日正式發(fā)布。目前該版本包含的特性已經(jīng)全部固定,主要包含以下五個:

      JEP 350,Dynamic CDS Archives

      JEP 351,ZGC: Uncommit Unused Memory

      JEP 353,Reimplement the Legacy Socket API

      JEP 354: Switch Expressions (Preview)

      JEP 355,Text Blocks (Preview)

      下面來逐一介紹下這五個重要的特性。

      Dynamic CDS Archives

      這一特性是在JEP310:Application Class-Data Sharing基礎(chǔ)上擴展而來的,Dynamic CDS
      Archives中的CDS指的就是Class-Data Sharing。

      那么,這個JEP310是個啥東西呢?


      我們知道在同一個物理機/虛擬機上啟動多個JVM時,如果每個虛擬機都單獨裝載自己需要的所有類,啟動成本和內(nèi)存占用是比較高的。所以Java團隊引入了CDS的概念,通過把一些核心類在每個JVM間共享,每個JVM只需要裝載自己的應(yīng)用類,啟動時間減少了,另外核心類是共享的,所以JVM的內(nèi)存占用也減少了。

      CDS 只能作用于 Boot Class Loader 加載的類,不能作用于 App Class Loader 或者自定義的 Class Loader
      加載的類。

      在 Java 10 中,則將 CDS 擴展為 AppCDS,顧名思義,AppCDS 不止能夠作用于 Boot Class Loader了,App Class
      Loader 和自定義的 Class Loader 也都能夠起作用,大大加大了 CDS 的適用范圍。也就說開發(fā)自定義的類也可以裝載給多個JVM共享了。

      Java 10中包含的JEP310的通過跨不同Java進(jìn)程共享公共類元數(shù)據(jù)來減少了內(nèi)存占用和改進(jìn)了啟動時間。

      但是,JEP310中,使用AppCDS的過程還是比較復(fù)雜的,需要有三個步驟:
      1、決定要 Dump 哪些 Class 2、將類的內(nèi)存 Dump 到歸檔文件中 3、使用 Dump 出來的歸檔文件加快應(yīng)用啟動速度
      這一次的JDK 13中的JEP 350 ,在JEP310的基礎(chǔ)上,又做了一些擴展。允許在Java應(yīng)用程序執(zhí)行結(jié)束時動態(tài)歸檔類,歸檔類將包括默認(rèn)的基礎(chǔ)層
      CDS(class data-sharing)存檔中不存在的所有已加載的應(yīng)用程序類和庫類。

      也就是說,在Java 13中再使用AppCDS的時候,就不在需要這么復(fù)雜了。

      ZGC: Uncommit Unused Memory

      在討論這個問題之前,想先問一個問題,JVM的GC釋放的內(nèi)存會還給操作系統(tǒng)嗎?

      GC后的內(nèi)存如何處置,其實是取決于不同的垃圾回收器的。因為把內(nèi)存還給OS,意味著要調(diào)整JVM的堆大小,這個過程是比較耗費資源的。

      在JDK 11中,Java引入了ZGC,這是一款可伸縮的低延遲垃圾收集器,但是當(dāng)時只是實驗性的。并且,ZGC釋放的內(nèi)存是不會還給操作系統(tǒng)的。



      而在Java 13中,JEP 351再次對ZGC做了增強,本次 ZGC
      可以將未使用的堆內(nèi)存返回給操作系統(tǒng)。之所以引入這個特性,是因為如今有很多場景中內(nèi)存是比較昂貴的資源,在以下情況中,將內(nèi)存還給操作系統(tǒng)還是很有必要的:

      * 1、那些需要根據(jù)使用量付費的容器
      * 2、應(yīng)用程序可能長時間處于空閑狀態(tài)并與許多其他應(yīng)用程序共享或競爭資源的環(huán)境。
      * 3、應(yīng)用程序在執(zhí)行期間可能有非常不同的堆空間需求。例如,啟動期間所需的堆可能大于稍后在穩(wěn)定狀態(tài)執(zhí)行期間所需的堆。
      Reimplement the Legacy Socket API

      使用易于維護和調(diào)試的更簡單、更現(xiàn)代的實現(xiàn)替換 java.net.Socket 和 java.net.ServerSocket API。

      java.net.Socket和java.net.ServerSocket的實現(xiàn)非常古老,這個JEP為它們引入了一個現(xiàn)代的實現(xiàn)。現(xiàn)代實現(xiàn)是Java
      13中的默認(rèn)實現(xiàn),但是舊的實現(xiàn)還沒有刪除,可以通過設(shè)置系統(tǒng)屬性jdk.net.usePlainSocketImpl來使用它們。

      運行一個實例化Socket和ServerSocket的類將顯示這個調(diào)試輸出。這是默認(rèn)的(新的):
      java -XX:+TraceClassLoading JEP353 | grep Socket [0.033s][info ][class,load]
      java.net.Socket source: jrt:/java.base [0.035s][info ][class,load]
      java.net.SocketOptions source: jrt:/java.base [0.035s][info ][class,load]
      java.net.SocketImpl source: jrt:/java.base [0.039s][info ][class,load]
      java.net.SocketImpl$$Lambda$1/0x0000000800b50840 source: java.net.SocketImpl
      [0.042s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base
      [0.042s][info ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base
      [0.043s][info ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base
      [0.044s][info ][class,load] java.net.DelegatingSocketImpl source:
      jrt:/java.base [0.044s][info ][class,load] java.net.SocksSocketImpl source:
      jrt:/java.base [0.044s][info ][class,load] java.net.ServerSocket source:
      jrt:/java.base [0.045s][info ][class,load]
      jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base [0.045s][info
      ][class,load] java.net.ServerSocket$1 source: jrt:/java.base
      上面輸出的sun.nio.ch.NioSocketImpl就是新提供的實現(xiàn)。

      如果使用舊的實現(xiàn)也是可以的(指定參數(shù)jdk.net.usePlainSocketImpl):
      $ java -Djdk.net.usePlainSocketImpl -XX:+TraceClassLoading JEP353 | grep
      Socket [0.037s][info ][class,load] java.net.Socket source: jrt:/java.base
      [0.039s][info ][class,load] java.net.SocketOptions source: jrt:/java.base
      [0.039s][info ][class,load] java.net.SocketImpl source: jrt:/java.base
      [0.043s][info ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800b50840
      source: java.net.SocketImpl [0.046s][info ][class,load]
      sun.net.PlatformSocketImpl source: jrt:/java.base [0.047s][info ][class,load]
      java.net.AbstractPlainSocketImpl source: jrt:/java.base [0.047s][info
      ][class,load] java.net.PlainSocketImpl source: jrt:/java.base [0.047s][info
      ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base
      [0.047s][info ][class,load] sun.net.ext.ExtendedSocketOptions source:
      jrt:/java.base [0.047s][info ][class,load] jdk.net.ExtendedSocketOptions
      source: jrt:/jdk.net [0.047s][info ][class,load] java.net.SocketOption source:
      jrt:/java.base [0.047s][info ][class,load]
      jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net
      [0.047s][info ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net
      [0.047s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions
      source: jrt:/jdk.net [0.047s][info ][class,load]
      jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net
      [0.048s][info ][class,load] jdk.net.LinuxSocketOptions source: jrt:/jdk.net
      [0.048s][info ][class,load]
      jdk.net.LinuxSocketOptions$$Lambda$2/0x0000000800b51040 source:
      jdk.net.LinuxSocketOptions [0.049s][info ][class,load]
      jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net [0.049s][info
      ][class,load] java.net.StandardSocketOptions source: jrt:/java.base
      [0.049s][info ][class,load] java.net.StandardSocketOptions$StdSocketOption
      source: jrt:/java.base [0.051s][info ][class,load]
      sun.net.ext.ExtendedSocketOptions$$Lambda$3/0x0000000800b51440 source:
      sun.net.ext.ExtendedSocketOptions [0.057s][info ][class,load]
      java.net.DelegatingSocketImpl source: jrt:/java.base [0.057s][info
      ][class,load] java.net.SocksSocketImpl source: jrt:/java.base [0.058s][info
      ][class,load] java.net.ServerSocket source: jrt:/java.base [0.058s][info
      ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base
      [0.058s][info ][class,load] java.net.ServerSocket$1 source: jrt:/java.base
      上面的結(jié)果中,舊的實現(xiàn)java.net.PlainSocketImpl被用到了。

      Switch Expressions (Preview)

      在JDK 12中引入了Switch表達(dá)式作為預(yù)覽特性。JEP
      354修改了這個特性,它引入了yield語句,用于返回值。這意味著,switch表達(dá)式(返回值)應(yīng)該使用yield,
      switch語句(不返回值)應(yīng)該使用break。

      在以前,我們想要在switch中返回內(nèi)容,還是比較麻煩的,一般語法如下:
      int i; switch (x) { case "1": i=1; break; case "2": i=2; break; default: i =
      x.length(); break; }
      在JDK13中使用以下語法:
      int i = switch (x) { case "1" -> 1; case "2" -> 2; default -> { int len =
      args[1].length(); yield len; } };
      或者
      int i = switch (x) { case "1": yield 1; case "2": yield 2; default: { int len
      = args[1].length(); yield len; } };

      在這之后,switch中就多了一個關(guān)鍵字用于跳出switch塊了,那就是yield,他用于返回一個值。和return的區(qū)別在于:return會直接跳出當(dāng)前循環(huán)或者方法,而yield只會跳出當(dāng)前switch塊。

      Text Blocks (Preview)

      在JDK 12中引入了Raw String Literals特性,但在發(fā)布之前就放棄了。這個JEP在引入多行字符串文字(text
      block)在意義上是類似的。

      text block,文本塊,是一個多行字符串文字,它避免了對大多數(shù)轉(zhuǎn)義序列的需要,以可預(yù)測的方式自動格式化字符串,并在需要時讓開發(fā)人員控制格式。

      我們以前從外部copy一段文本串到Java中,會被自動轉(zhuǎn)義,如有一段以下字符串:
      <html> <body> <p>Hello, world</p> </body> </html>
      將其復(fù)制到Java的字符串中,會展示成以下內(nèi)容:
      "<html>\n" + " <body>\n" + " <p>Hello, world</p>\n" + " </body>\n" +
      "</html>\n";
      即被自動進(jìn)行了轉(zhuǎn)義,這樣的字符串看起來不是很直觀,在JDK 13中,就可以使用以下語法了:
      """ <html> <body> <p>Hello, world</p> </body> </html> """;
      使用“”“作為文本塊的開始符合結(jié)束符,在其中就可以放置多行的字符串,不需要進(jìn)行任何轉(zhuǎn)義。看起來就十分清爽了。

      如常見的SQL語句:
      String query = """ SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` WHERE
      `CITY` = 'INDIANAPOLIS' ORDER BY `EMP_ID`, `LAST_NAME`; """;
      看起來就比較直觀,清爽了。

      總結(jié)

      以上,就是JDK13中包含的5個特性,能夠改變開發(fā)者的編碼風(fēng)格的主要有Text Blocks和Switch
      Expressions兩個新特性,但是這兩個特性還處于預(yù)覽階段。

      而且,JDK13并不是LTS(長期支持)版本,如果你正在使用Java 8(LTS)或者Java 11(LTS),暫時可以不必升級到Java 13.



      參考資料: https://openjdk.java.net/projects/jdk/13/
      <https://openjdk.java.net/projects/jdk/13/>
      https://metebalci.com/blog/what-is-new-in-java-13/
      <https://metebalci.com/blog/what-is-new-in-java-13/>
      https://www.jianshu.com/p/890196bf529a <https://www.jianshu.com/p/890196bf529a>

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          春色导航 | 操逼视频网站在线观看 | 天天爱天天干天天爽 | 成年人性生活免费视频 | 国产欧美在线播放 | 欧美乱妇狂野欧美在线视频 | 玩弄折磨虐女91调教吹潮 | 国产一级www | 欧美日韩人妻精品一区二区 | 操骚屄视频 |