1 簡介
Java SE 6(Java Platform Standard Edition 6)的一個主要設計原則就是以性能缺陷為目標,通過當前最流行的一些 Java 基准測試以及與 Java 社區的緊密協作來確定對性能影響最大的增強關鍵領域,從而提高性能和可伸縮性。
本指南將概述 Java Standard Edition 6 中新增功能和可伸縮性改進,同時提供各種行業標准和內部開發的基准測試結果,以便演示這些性能改進的影響。
2 新增功能和性能增強
Java SE 6 引入了一些新的功能和性能增強,為平台中的許多領域都提供了性能改進。這些改進包括:同步性能優化、編譯器性能優化、新的並行縮並垃圾收集器(Parallel Compaction Collector)、工效更高的並發低停頓垃圾收集器(Concurrent Low Pause Collector),以及應用程序的啟動性能。
2.1 運行時性能改進
2.1.1 偏向鎖
偏向鎖(Biased Locking)是一個優化的類,它通過消除與 Java 語言同步原語相關的原子操作改進無競爭同步性能。這些優化依賴於屬性,它們不僅是大多數無競爭的監視器,而且在它們的生命期內最多被一個線程鎖定。
對象通過監視器輸入字節碼或同步方法調用,“偏向”於第一個獲取監視器的線程;隨後與監視器相關的操作可以通過該線程執行而不需使用原子操作,從而獲得更好的性能,特別在多處理器機器上,這種性能改進尤為明顯。
由多線程而不是單線程對“偏向”對象的鎖定嘗試,將引起相對較大的操作開銷,由此偏向被撤銷。消除原子操作的好處必需超過鎖定撤銷懲罰從而使該優化有利可圖。
使用大量無競爭的同步將獲得顯著的速度提升,而其他使用某些鎖定模式的應用程序運行可能緩慢。
偏向鎖在 Java SE 6 以及未來版本中將被默認啟用。要禁用偏向鎖,請向命令行添加 -XX:-UseBiasedLocking。
要了解關於偏向鎖的更多詳細信息,請參閱由 Kenneth Russell 和 David Detlefs 撰寫的《ACM OOPSLA 2006》文章:“使用偏向鎖和批量重新偏向(Bulk Rebiasing)消除與同步相關的原子操作”。
2.1.2 鎖粗化
Java SE 6 有一些鎖定模式。在這些模式下鎖被釋放,然後在一段代碼內被重新獲得,在此之間沒有可觀察的操作出現。在那樣的情況下,在 hotspot 中實施的鎖粗化優化技術消除了加鎖和解鎖的操作(當一個鎖被釋放時,在解鎖與下次加鎖之間又沒有意義的事情可干,那麼可以重新獲得該鎖)。通過擴大現存同步區域基本上減少了同步工作的總量。圍繞一個循環執行此操作可能導致一個鎖被長期持有,因此鎖粗化技術只在非循環的控制流上使用。
該功能默認使用。要禁用此功能,請向命令行添加下列選項:-XX:-EliminateLocks
2.1.3 自適應自旋
自適應自旋是一項優化技術。在該優化技術中,兩階段自旋再阻塞(spin-then-block)策略被嘗試競爭同步輸入操作的多線程使用。該技術啟用多線程以避免對性能產生不合需要的影響,例如翻譯後援緩存器 (Translation Lookaside Buffers,TLB)的上下文切換和重新存入。該性能是“自適應的”,因為自旋持續時間由策略決策確定,基於以下因素:在相同監視器上的自旋嘗試成功率和/ 或最新自選嘗試失敗率,以及最新鎖的所有者狀態。
要了解自適應自旋的更多信息,請參閱 Dave Dice 的演示文稿:"Java SE 6 中的同步"
在 x86 和 amd64 平台上支持大頁面堆
在 x86 和 amd64 平台上 Java SE 6 支持大內存頁面堆。大內存頁面堆(Large page heap)幫助操作系統避免開銷巨大的翻譯後援緩存器(Translation-Lookaside Buffer,TLB)錯失,從而使內存密集型應用程序更好地運行(單個 TLB 就可以代表較大的內存范圍)。
請注意大頁面內存有時可以對系統性能產生負面影響。例如,當大量內存被一個應用程序固定,可能會產生常規內存不足,並引起其它應用程序中過度地分頁,從而使整個系統運行緩慢。還請注意,對於一個已經啟動很長時間的系統,過多的碎片使得系統不能保留大頁面內存。當這種情況發生時,操作系統可能轉而采用常規頁面。而且,可以通過設置 -Xms == -Xmx、 -XX:PermSize == -XX:MaxPermSize 和 -XX:InitialCodeCacheSize == -XX:ReserverCodeCacheSize 最小化這種影響。
大頁面的另一個可能的缺陷是,永久保存區域和代碼緩存的默認頁面大小可能因為使用大頁面而更大;當頁面大小比這些內存區域的默認頁面大小大時這方面的問題就要特別值得注意。
在 Solaris 操作系統上默認啟用對大頁面的支持。在 Windows 和 Linux 操作系統上默認關閉對大頁面的支持。請向命令行添加 -XX:+UseLargePages 以便啟用該功能。請注意,操作系統配置更改可能要求啟用大頁面。要了解更多信息,請參閱 Sun Developer Network 上的 關於 Java 對大內存頁的支持 文檔。
2.1.5 數組復制性能改進
方法指令 System.arraycopy() 在 Java SE 6 中得到進一步增強。當沒有出現重疊時,手工編碼程序集存根用於每種頁面類型大小。
2.1.6 HotSpot™ 客戶機編譯器中的後台編譯。
在 Java SE 6 之前,HotSpot 客戶機(HotSpot Client)編譯器在後台中不能默認編譯 Java 方法。結果,超線程(Hyperthreaded)或多進程(Multi-processing)系統不能利用多余的 CPU 周期來優化 Java 代碼的執行速度。目前,在 Java SE 6 HotSpot 客戶機編譯器中啟用了後台編譯。
2.1.7 針對 HotSpot™ 客戶機編譯器的線性掃描寄存器分配算法
HotSpot 客戶編譯器公開了一種新的線性掃描寄存器分配算法。該算法依賴於靜態單一分配(Static Single Assignment,SSA)形式。這一做法的另外好處是提供一個簡化了的數據流分析和較短的動態時間間隔,這樣取得了在編譯時間和程序運行時之間產生較好的折衷。這種新的算法已經在許多內部基准和符合行業標准基准上提供了大約 10% 的性能改進。
要了解關於這個新功能的詳細信息,請參閱以下文章:針對 Java HotSpot™ 客戶機編譯器的線性掃描寄存器分配
2.2 垃圾收集2.2.1 並行縮並垃圾收集器
並行縮並是一種功能,它啟用並行垃圾收集器來以並行方式執行主要收集操作,從而導致較低的垃圾收集開銷和更好的應用程序執行能力,對於帶有大內存堆的應用程序效果特別明顯。該垃圾收集器最適合具有兩個或多個處理器或硬件線程的平台。
在 Java SE 6 之前,年輕代以並行方式收集垃圾,主要收集操作使用單線程執行。對於經常執行大的收集(major collection)操作的應用程序來說,這將對可伸縮性產生不利影響。
在 JDK 6 中默認使用並行縮並,但是可以通過向 JDK 5 更新 6 以及未來版本中的命令行添加 -XX:+UseParallelOldGC 禁用它。
請注意,並行縮並在與並發標記清除(mark-sweep)收集器結合使用時不可用;它只能和並行年輕代收集器(-XX:+UseParallelGC)一起使用。下列參考文檔提供了可用收集器和使用建議的更多詳細內容。
關於並行縮並收集(Parallel Compaction Collection)的更多詳細信息,請參閱 Java SE 6 發行說明 。有關垃圾收集的更多信息,HotSpot 內存管理白皮書 描述了在 HotSpot 中的各種可用收集器、何時使用並行縮並,以及算法的高層描述方面的建議。
2.2.2 並發低停頓垃圾收集器:並發標記清除收集器增強
並發標記清除收集器性能已經得到了增強以便為 System.gc() 和 Runtime.getRuntime().gc() 方法指令提供並發收集。在 Java SE 6 之前,為了收集整個堆,這些方法停止所有應用程序線程,這樣有時會導致在使用大內存堆的應用程序中很長時間的停頓。結合並發標記清除收集器所實現的目標,這個新功能將使收集器在整個堆收集期間保持盡可能短時間的停頓。
要啟用該功能,向 Java 命令行添加 -XX:+ExplicitGCInvokesConcurrent 選項。
在並發標記清除(CMS)收集器中,並發加標記的任務現在在多處理器平台上以並行的方式執行。這顯著地減少了並發加標記周期的持續時間,並使得收集器更好地支持帶有較多線程的應用程序,從而獲得很高的對象分配率。在大型多處理器機器上此種性能改進效果尤為突出。
關於這些新功能的更多詳細信息,請參閱 Java SE 6 發行說明。
2.3 Java Virtual Machine 6.0 中的工效特性
在 Java SE 5 中,引入了與平台有關的垃圾收集器的默認選擇、堆大小和運行時編譯器,以便當要求較少的命令行調優時更好地滿足不同類型的應用程序需求。其中還引入了新的調優標志,以便使用戶指定需要的行為來依次啟用垃圾收集器,動態地調整堆的大小,直至滿足指定行為。在 Java SE 6 中,默認選擇性能已經得到進一步增強,改進了應用程序運行時性能並提高了垃圾收集器效率。
下列圖表對比了 Java SE 5 和 Java SE 6 Update 2 之間即開即用 SPECjbb2005™ 的性能。在 Sun Fire V890 上使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 運行 Solaris 10 進行此項測試:
在每種情況下基准都不使用任何性能標志而運行。請參看 SPECjbb 2005 基准披露
下列圖表對比了Java SE 5 和 Java SE 6 Update 2 之間的 I/O 性能。在
Sun Fire V890 上使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 運行 Solaris 10 進行此項測試:
在每種情況下基准都不使用任何性能標志而運行。
我們對比了 Java SE 5 和 Java SE 6 Update 2 之間的 VolanoMark™ 2.5 的性能。VolanoMark 是一個純 Java 基准,用來測量 (a) 原始服務器性能和 (b) 服務器網絡可伸縮性性能。在這個基准中,客戶端積累了多達 4000 個並發套接字連接。只有那些成功積累連接多達 4000 個的虛擬機(VM)才能通過測試。在兩種原始性能和網絡可伸縮性測試中,分數越高,結果越好。
此項測試的平台為使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 的 Sun Fire V890,操作系統為 Solaris 10:
在每種情況下,我們不使用任何性能標志而運行在回環(loopback)模式中的基准。顯示結果基於相對吞吐量(使用 400 個回環連接每秒發送的消息)。
針對 Java SE 5 的完整 Java 版本是:
java 版本 “1.5.0”
Java(TM) 2 Runtime Environment,Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64,混合模式)
針對 Java SE 6 的完整 Java 版本是:
java 版本 “1.6.0_02”
Java(TM) 2 Runtime Environment,Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64,混合模式)
請閱讀 VolanoMark™ 2.5 基准測試
在 Java SE 6 中的其他性能改進包括:
在服務器級機器上,不低於或等於 1 秒的指定最大停頓時間目標將啟用並發標記清除收集器。
允許垃圾收集器根據需要(在規定的限制條件下)在年老代(tenured generation)和年輕代(young generation)邊界之間遷移,從而獲得更好的性能目標。該機制默認關閉;要激活該機制,將下列代碼添加到命令行:option -XX:+UseAdaptiveGCBoundary 。
對於串行(-XX:+UseSerialGC)收集器和並行年輕代(- XX:+ParNewGC)收集器 ,提升失敗處理默認打開。如果在年老代中沒有足夠的空間來提升所有需要提升的對象,該項功能允許收集器啟動小的收集(minor collection),然後把它取回來。
已經實現了把來自年輕代的對象復制到在並行清除收集器中的年老代的可選命令。該項功能的意圖是降低錯過在年老代已經被訪問的對象這類緩存錯失次數。默認啟用該項功能。要禁用該功能,請向命令行添加 -XX:-UseDepthFirstScavengeOrder。
在 x86 平台上默認的年輕代的大小已經增加到 1MB。
系統已經增加了並發標記清除收集器年輕代(Young Generation)的默認大小。
最小年輕代大小從 4MB 增加到 16MB。
針對年輕代的全部堆比例從 1/15 增加到 1/7。
目前,並行標記清除(CMS)收集器默認使用生存空間,且其默認大小也有增加。
這些變化的主要影響是通過減少垃圾收集開銷來提高應用程序性能。但是,由於默認年輕代的大小比較大,應用程序也可能看到更大的年輕代停頓時間和更大內存占用量。
2.4 客戶端性能增加
2.4.1 類數據共享中的新類列表
要減少應用程序的啟動時間和內存占用量, Java SE 5.0 引入了一個稱作“類數據共享(Class Data Sharing,CDS)”的功能。在 32 位平台上,這種機制按如下方式工作: Sun 提供了一個安裝程序,從系統 jar(jar 文件包含所有 Java 類庫,稱作 rt.jar)文件中加載類集合到一個專有內部表示法,並將該表示法轉儲到一個稱作“共享歸檔”的文件中。關於後續的 JVM 調用,共享歸檔是內存映射輸入的,從而節省了加載這些類的開銷,並允許許多 Java 虛擬機的元數據用於在被多個 JVM 進程之間共享的這些類。
在 Java SE 6.0中,在“共享歸檔”中的類列表已經被更新,以便更好反映對系統 jar 文件的更改。
2.4.2 引導類加載器的性能改進
已經增強了Java 虛擬機的引導(boot)和擴展(extension)類加載器性能以便改進 Java 應用程序的冷啟動時間。在 Java SE 6 之前,打開系統 jar 文件引發 Java 虛擬機要讀取一個 1 MB 大小的 ZIP 索引文件。當文件沒有在磁盤緩沖區內時,該索引文件將文件轉換為大量磁盤搜索活動。啟用“類數據共享”,Java 虛擬機現在可以提供一個“元索引(meta-index)”文件(位於 jre/lib 中),其中包含在 jar 文件中所含包的高層次信息。
當 Java 應用程序類被加載時,這有助於 JVM 避免打開在引導和擴展類路徑上的所有 jar 文件。要了解更多詳細信息,查看錯誤 6278968}。
下面我們給出了 Java SE 5 和 Java SE 6 Update 2 的應用程序啟動時間性能對比圖。此測試的運行環境為 1 GB 內存的 Intel Core 2 Duo 2.66GHz 台式機。
應用程序啟動對比結果顯示了系統的相對性能(數值越小,性能越好),並且在基准運行的每種情況中都沒有添加任何性能標志。
我們還比較了 Java SE 5 和 Java SE 6 Update 2 所需內存占用量的大小。
這項測試的運行環境是 1GB 內存的 Intel Core 2 Duo 2.66GHz 台式機:
內存占用量對比結果顯示了系統的相對性能(數值越小,性能越好),並且在運行基准的每種情況中都沒有添加任何性能標志。
盡管新增了許多功能,但是 Java 虛擬機的核心內存利用率卻大大削減,這使其對系統內存的實際影響比 Java SE 5 要低很多。
2.4.3 啟動畫面功能
Java SE 6 提供了一個使應用程序在虛擬機啟動前顯示啟動畫面的解決方案。目前,Java 應用程序的啟動程序能夠對圖像進行解碼,並在簡單的未修飾窗口中顯示該圖像。
2.4.4 Swing 的真正雙重緩沖
現在 Java SE 6 已經啟用了 Swing 的真正雙重緩沖功能。Swing 過去在應用程序的基礎上提供雙重緩沖;現在,在每一個窗口(per-window)基礎上提供雙重緩沖,並且將原生暴露事件直接復制到雙重緩沖區。這樣顯著地提高了 Swing 的性能,特別在遠程服務器上效果尤為明顯。
有關更多詳細信息,請訪問 Scott Violet 的博客。
2.4.5 改進 windows 系統的呈現功能
UxTheme API 允許在 Microsoft Windows 系統上啟用窗口控制的標准外觀呈現功能。Java SE 6 采用 UxTheme API 提高了 Swing Systems 外觀的保真性。
3 新平台支持
有關完整信息,請參閱 支持 Java SE 6 的操作系統配置 圖表。
3.1 運行環境
3.1.1 Windows Vista
Windows Vista Ultimate Edition、Home Premium Edition、Home Basic Edition、Enterprise Edition、Business Edition、Windows XP Home 和 Professional、2000 Professional、2000 Server 以及 2003 Server 都支持 Java SE 6。
4 深入學習
4.1 Java 性能門戶
有關 Java 性能最佳實踐、文檔、工具、常見問題解答(FAQ)、代碼樣例和白皮書(White Papers)以及 Java 性能新聞中的其他最新信息,請訪問 Java 性能門戶。
在此給出了 Java SE 6.0 三個特殊的相關性能鏈接:
4.1.1 Java SE 6 HotSpot[tm] 虛擬機垃圾收集調優
Java SE 6 HotSpot[tm] 虛擬機垃圾收集調優 文檔針對 Java SE 6 垃圾收集(GC)調優概念和技術進行了擴展,這方面內容詳見 使用 5.0 Java 虛擬機進行垃圾收集調優 文檔。
4.1.2 jvmstat 3.0
jvmstat 3.0 主頁提供了內建在 Java SE 6 中的輕量級性能監控功能,並解釋了如何使用這些工具監控 6.0 HotSpot Java Virtual Machines、HotSpot 1.5.0、HotSpot 1.4.2 以及 1.4.1 JVM。
4.2 Java SE 6 文檔
請閱讀 Java SE 6 文檔,其中包括 新功能及其增強 和 Java Platform,Standard Edition 6 概述。
4.3 性能監控與管理
4.3.1 HotSpot VM 中的 DTrace 探測器
4.3.2 新的監控、管理和診斷功能
4.3.3 在 Solaris OS 上使用 Java SE 6 的可觀察性
4.4 基准測試
4.4.1 SPECjbb 2005
SPECjbb2000 是標准性能評估機構(Standard Performance Evaluation Corporation,SPEC)提供的一款基准測試工具。引用的性能建立在 Sun 內部軟件測試基礎之上,並遵循上面列舉的方法。
有關最新的 SPECjbb2005 測試結果,請訪問 http://www.spec.org/osg/jbb2005。
4.4.2 VolanoMark™ 2.5
VolanoMark™ 版本 2.5 是 Volano LLC ( http://www.volano.com/ ) 提供的一款基准測試工具。