歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> 學習Linux >> 生產環境 JDK6 升級至 JDK8

生產環境 JDK6 升級至 JDK8

日期:2017/3/6 9:27:32   编辑:學習Linux

生產環境 JDK6 升級至 JDK8


生產環境 JDK6 升級至 JDK8


由於 Oracle 已經不對 JDK6 和 JDK7 進行支持,同時為了利用 G1 收集器。所以我們在生產環境中,將項目從 JDK6 升級至 JDK8,並將垃圾收集器由 CMS 換成了 G1。下面對這次升級作一個總結,並且給出一些大家可能需要用到的資源。

升級指引

升級前首先需要了解一下 Oracle 對 JDK 各個版本的支持時間,JDK6, JDK7 分別於 2013, 2015 年停止了公開更新(public update),而 JDK8 將於 2017 年,或者更晚的時間,停止公開更新,詳細內容可以參考 Oracle Java SE Support Roadmap。

Java 版本之間是有二進制向後兼容性的,即 JDK8 的虛擬機可以運行由 JDK7, JDK6 編譯的 class 文件。如果有例外的話,Oracle 會在升級中明確說明。但是如果用 JDK8 了,還將代碼編譯成之前版本的類文件,就意味著無法使用 JDK8 中的新語法特性。Oracle 在大版本之間的升級,都會提供兼容性指南,例如 Compatibility Guide for JDK 8,Java SE 7 and JDK 7 Compatibility。兼容性指南包含的主要內容包括:

  • 二進制兼容性
  • 源代碼兼容性
  • 行為兼容性
  • 類文件變化
  • Java SE 與上一版本相比不兼容的地方
  • JDK 與上一版本相比不兼容的地方
  • Java SE 中移除的特性
  • JDK 中移除的特性
  • 不建議使用的 API

二進制兼容性

JDK7 編譯的代碼可以在 JDK8 下運行,JDK8 下編譯的代碼不可以在之前版本的 JDK 中運行 。

源代碼兼容性

使用了 JDK8 語法新特性的源代碼,不能在之前版本的 Java 平台上編譯。不建議使用的 API 在用新 javac 編譯時,會給出警告,除非通過 -nowarn 關閉。sum.* 下的 API 有所變化,所以,一定要記得不要使用這個包下的 API,不然升級會很痛苦。

行為兼容性

行為兼容性意味著同樣的輸入,有著同樣的行為。Java 平台中會有一些故意未指定的行為,在不同的 JDK 版本中,可能會有變化,所以代碼不應該依賴於這些行為。如果 JDK 版本變了,行為也變了,可能說明代碼裡有 bug。

類文件

JDK8 編譯的類文件,版本號為 52.0

JDK 及 Java SE 與上一版本的不兼容性

這一部分內容比較多,如果從 JDK7 升級至 JDK8,可以參考 Compatibility Guide for JDK 8;如果從 JDK6 升級至 JDK8,需要同時參考 Compatibility Guide for JDK 8 和 Java SE 7 and JDK 7 Compatibility。

這一部分內容裡包含了源代碼不兼容性,例如原來在 JDK7 下可以編譯的代碼,在 JDK8 下就不能編譯了。這類錯誤還是比較好查的,編譯一下就可以���出這類錯誤。

或者是一些 GC 選項會被忽略,例如 PermSize

或者是類文件中添加了一些新內容,例如 StackMapTable ,在運行時會對類文件的這個字段進行驗證,一些可能會調整字節碼的工具,需要更新這個字段。例如代碼覆蓋率統計工具,這些工具如果調整了字節碼,又沒有對 StackMapTable 進行更新。那麼高版本的 JDK 就無法運行經過調整的字節碼,在字節碼校驗階段就會失敗。

或者是同一份代碼,由於 JDK8 引入的特性,生成不同字節碼,最終導致 JDK8 下無法正常運行。這類錯誤通常只會在運行時才體現出來,比較難以察覺。例如我在這篇 JDK8 中的類型推斷與重載解析 中描述的這類情況。對這類情況,我們應該做到:

  • 平時多寫測試用例
  • 用 tcpcopy 引線上流量打壓

這樣,可以讓運行時錯誤或者行為不兼容性更早地暴露出來

GC

從 JDK6 向上升級,在 GC 方面比較重要的就是 G1 這個垃圾收集器。G1 垃圾收集器在 JDK6u14 中作為實驗特性發布,在 JDK7 中正式發布。未來,在 JDK9 中,G1 將會作為默認的垃圾收集器,可見 G1 已經達到了比較成熟的階段。所以在 JDK8 中完全可以使用 G1。

而 G1 中比較重要的特性包括:

  • 同時實現了新生代和老年代兩種 GC 算法
  • 各代之間不再有物理隔離,虛擬機管理的內存分為多個 region
  • 通過設置 GC 停頓的期望時間來調優(-XX:MaxGCPauseMillis)

使用建議包括:

  • 適用於管理大內存的場景
  • 適用於對延遲要求高於吞吐的場景
  • 總是將詳細的 GC 日志記錄在 log 中
  • 總是打開 -XX:+ParallelRefProcEnabled 選項,實際環境中發現處理引用的過程確實也比較耗時
  • 避免 Humongous 區域,即單個對象大小大於 region 區大小的 50%
  • 盡力避免 Full GC

注意事項包括:

  • 不要再設置新生代大小了,通過調整停頓時間,G1 會自動調整新生代大小
  • 停頓時間只是期望時間,並不保證 STW 一定在這個時間內完成。根據經驗,如果將停頓時間設置為 x, 那麼 50% 的 GC 會在 x ms 內完成

在此次升級過程中,我看過的最重要的資料是一份 presentation: G1 Garbage Collector Details and Tuning。其中對 G1 中的重要特性,原理,使用建議,參考資料進行了說明,強烈建議閱讀。

除此之外,還有幾個和 G1 相關的博客可以參考:

  • G1GC Concept and Performance Tuning
  • Poonam's Weblog

第三方庫

升級 JDK8 的過程中,一些第三方庫也需要同步更新。比較重要的一個原因在於,一些庫是依賴類文件格式的,如果把代碼編譯到 JDK8 的版本,那麼這些庫也需要同步更新。例如:

  • 代碼覆蓋率工具:Emma 不支持 JDK8,可以選用 Jacoco
  • Spring: 4.x 版本才全面支持 JDK8,之前的版本可能無法正確讀取類文件。可以參考 How Spring achieves compatibility with Java 6, 7 and 8。

同時,也需要注意,第三方庫的升級,也會帶來另外一些問題。例如,我們在升級 Spring 的過程中,就遇到了死鎖問題。

參考資料

  • Upgrading major Java versions
  • Compatibility Guide for JDK 8
  • Java SE 7 and JDK 7 Compatibility
  • G1 Garbage Collector Details and Tuning
  • Spring Framework 4.0 M1 & 3.2.3 available

在CentOS7上安裝JDK1.8

CentOS 搭建JDK環境

CentOS6.3安裝JDK和環境配置

本文永久更新鏈接地址:

http://xxxxxx/Linuxjc/1145139.html TechArticle

Copyright © Linux教程網 All Rights Reserved