1. 程式人生 > >優化之誤!

優化之誤!

解決方法 它的 代碼 可用 空間 block pil 分配 content

假設在jvm啟動時load飆高,然後逐漸正常的情況 ,我們常常會懷疑到 JIT 編譯的問題。

添加啟動時編譯的核心數肯定是一個有效的解決的方法,可是這個參數在啟動時設置後,假設正常執行時不須要這麽多核來工作。

你又不能在jvm已經啟動的情況下動態減少這個參數。

所以使用-XX:+TieredCompilation進行分層編譯,能夠緩解這個問題,其實也有非常多case使用這個參數攻克了jvm啟動時load飆高的問題。


可是。假設打開分層編譯,c1,c2的編譯結果會比未分層的c2結果占用更大的CodeCache,非常可能會超過默認的96m空間。

即使沒有占滿CodeCache,假設一次回收的空間較大,比方回收後可用空間為30m,可是每次編譯的代碼僅僅有幾百字節到幾k,那麽可用空間將會嚴重碎片化。


更可悲的是jdk7中,維護這個可用空間的是一個鏈表,查詢到一個特定大小的連續空間函數largest_free_block()是加鎖的。用一個加鎖的函數訪問一個巨大的列表,

結果可想而知。



也就是說,假設你不小心使用了jdk7的沒有patch過的版本號。打開了 -XX:+TieredCompilation參數,它不但不能優化,反而會由於argest_free_block()占用掉整個cpu。


詳細請看:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006952

之所以查到這個bug,正是我們的一個應用踩到這個雷了。應用被-XX:+TieredCompilation參數拖死。


由於是虛擬機,我們如今的解決方法是在啟動時動態分配給虛擬機很多其它的內核加快JIT編譯,正常啟動後將虛擬機內核數恢復正常。



優化之誤!