一步步優化JVM七:其他

邊緣問題

   在某些場景下,按照前面的一步步優化指導無法產生效果。這一節說明一下這些情況。

   一些應用分配了一些少量的非常大的長時間存活的對象。這樣的場景需要需要young代的空間比old代更大。

   一些應用會經歷很少的對象轉移。這樣的場景可能需要old代的空間遠遠大於存活對象的大小,由於old的佔用量增長率很小。

   一些應用有小延遲需求,會使用CMS垃圾回收器,而且使用小young代空間(以致於MinorGC時間更短),以及大的old代空間。在這種配置下,對象會快速的從young代移動到old代,替代了高效老化對象。另外,CMS垃圾回收移動後的對象,碎片的可能性通過大的old代空間來解決。

   下一節介紹一些其他的HotSpot VM選項來提升應用的性能。

其他一些的性能命令行選項

   幾個可選的前面有提到的命令選項可以用來提升Java應用的延遲和吞吐量性能,這些選項是通過JIT編譯器代碼優化以及其他的HotSpot VM優化能力。下面介紹這些特性以及相適應的命令選項。

   最新和最大優化
   當新的性能優化集成到HotSpot VM中之後,可以通過-XX:+AggressiveOpts選項來啓用。

   通過選項來引入新的優化,可以把最新及最大的優化和以及經過長時間使用證明是穩定的優化分離開。應用通常更希望獲得更好的穩定性,畢竟最新的優化可能會導致未知的問題。但是如果應用需要提升任何可以提升的性能優化的時候,可以使用命令選項來啓用這些優化。

   當新的優化被證明是穩定的之後,他們會被默認使用,也許需要升級幾個版本之後纔會變成默認。

   使用-XX:+AggressiveOpts命令選項之後,需要考慮到性能的提升,同樣也需要考慮到性能提升所帶來的不穩定風險。

   逃避分析

   逃避分析是一個種分析Java對象範圍的技術,在特殊情況下,一個線程分配的對象可能被另外一個線程使用,這個對象就叫着“逃避”。如果對象沒有逃避,額外的優化技術可以應用,因此,這種優化技術叫做逃避分析。

   在HotSpot VM裏面的逃避分析優化可以通過命令行選項:

   -XX:+DoEscapeAnalysis
   
   這是在Java 6 update 14中引入的,而且自動啓用通過-XX:+AggressiveOpts。在Java 6 update 23中是默認開啓的。

   通過逃避分析,HotSpot VM JIT編譯器,可應用下面的優化技術:

   1、對象爆炸:對象爆炸是一種對象的屬性存儲在Java堆以外而且可能潛在的消失。比如說,對象屬性可以直接被放置到內存的寄存器裏面或者對象被分配棧裏面而不是堆裏面。

   分等級替換:分等級替換是一種用來減少內存使用的優化技術,考慮下面的Java類,表現爲保存長方形的長和寬:
public class Rectangle {
  int length;
  int width;
}
   HotSpot VM可以優化內存分配和使用非逃避的Rectangle類的實例通過把長和寬都直接存儲到CPU的寄存器而不是分配Rectangle對象,結果是當時需要使用長和寬屬性的時候,不需要再複製到CPU的寄存器。這個可以減少內存的讀取。

   2、線程棧分配:顧名思義,線程棧分配是一種把對象分配到線程棧中,而不是Java堆裏面的優化技術。一個對象永遠不逃避,就可以放置到線程棧框架裏面,由於沒有其他線程需要看到這個對象。線程棧分配可以減少對象分配到Java堆,可以減少GC的頻率。

   3、消滅同步:如果線程分配的對象從來不會逃避,而且這個線程鎖定了這個對象,這個鎖可能會被JIT編譯器消滅,畢竟沒有其他線程會使用這個對象。

   4、消滅垃圾回收讀寫障礙:如果線程分配的對象從來不會逃避,只會被當前線程使用,所以在其他對象裏面存儲它的地址不需要障礙。讀或者寫障礙只有在對象會被其他線程使用的時候纔有需要。

有偏見的鎖

   有偏見的鎖是使得鎖更偏愛上次使用到它線程。在非競爭鎖的場景下,即只有一個線程會鎖定對象,可以實現近乎無鎖的開銷。

   有偏見的鎖,是在Java 5 update 6引入的。通過HotSpot VM的命令選項-XX:+UseBiasedLocking啓用。

   Java 5 HotSpot JDK需要明確的命令來啓用這個特性,在使用-XX:+AggressiveOpts選項,有偏見的鎖會Java 5中會被自動啓用。在Java 6中是默認啓用的。

   各種經歷告訴我們這個特性對大多數應用還是非常有用的。然後,有一些應用使用這個屬性不一定能夠表現的很好,比如,鎖被通常不被上次使用它的同一個線程使用。對於Java應用來說,由於stop-the-world安全點操作需要取消偏見,這樣可以通過使用-XX:-UseBiaseLocking來獲得好處。如果你不清楚你的應用是什麼情況,可以通過分別設置這兩個選項來測試。

大頁面

   在計算機系統中,內存被分爲固定大小的區塊,這個區塊就叫做頁(page)。內存的存取是通過程序把虛擬內存地址轉換成物理內存地址實現的。虛擬到物理地址是在一個塊表裏面映射的。爲了減少每次存取內存的時候使用頁表的消耗,通常會使用一種快速的虛擬到物理地址轉換的緩存。這個緩存叫做轉換後備緩衝區(translation lookaside buffer),簡稱TLB。

   通過TLB來滿足虛擬到物理地址的映射請求,會比遍歷頁表來找到映射關係快很多,一個TLB通常包含指定數量的條目。一個TLB條目是一個基於頁大小虛擬到物理地址映射,因此,更大的頁大小允許一個條目或者一個TLB有更大的內存地址範圍。在TLB中有更廣泛的地址,更少的地址轉換請求在TLB中不命中,就可以減少遍歷頁表(page table)操作。使用大頁的目的就是減少TLB的不命中。

   Oracle solariz,Linux 以及Windows都支持HotSpot VM使用大頁。通常處理器可以支持幾種頁大小,不過不同的處理器各不相同。另外,操作系統配置需要使用大頁。

   下面說說怎麼樣在Linux下使用大頁(Large Page)

Linux下的大頁面
  在寫作本書的時候,在Linux下使用大頁,除使用-XX:+UseLargePages命令選項以外,需要修改操作系統配置。Linux的修改操作具體和發行版本以及內核有關係。爲了合理的啓用Linux下的大頁,可以徵詢Linux管理員的意見或者閱讀Linux發行文檔。一旦使用了Linux操作系統配置已經修改,-XX:+UseLargePage命令行選項就必須要使用了。比如:
   $ java -server -Xmx1024m -Xms1024m -Xmn256m -XX:+UseLargePages ...
  如果大頁沒有被合理設置,HotSpot VM同樣會接受-XX:+UseLargePages是一個有效的選項,不過會報告無法獲取大頁,而且會退回操作系統的默認頁大小。


PS:打完收工,其實翻譯挺無聊和挺累的

我的網站:趕驢記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章