天天看點

JVM調優總結

調優總結

年輕代大小選擇

響應時間優先的應用:盡可能設大,直到接近系統的最低相應時間限制(根據實際情況選擇)。在此種情況下,年輕代收集發生的頻率也是最小的。同時,減少到達年老代的對象。

吞吐量優先的應用:盡可能的設定大,可能到達gbit的程度。因為對響應時間沒有要求,垃圾收集可以并行進行,一般适合8cpu以上應用。

年老代大小選擇

響應時間優先的應用:年老代使用并發收集器,是以其大小需要小心設定,一般要考慮并發會話率和會話持續時間等一些參數。如果堆設定小了,會造成記憶體碎片,高回收頻率以及應用暫停而使用傳統的标記清除方式;如果堆大了,則需要較長的收集時間。最優化的方案,一般需要參考以下資料獲得:

       1. 并發垃圾收集資訊

       2. 持久代并發收集次數

       3. 傳統gc資訊

       4. 花在年輕代和年老代回收上的時間比例,減少年輕代和年老代花費的時間,一般會提高應用的效率。

吞吐量優先的應用

一般吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代。原因是,這樣可以盡可能回收掉大部分短期對象,減少中期的對象,而年老代盡存放長期存活的對象。

較小堆引起的碎片問題

因為年老代的并發收集器使用标記、清除算法,是以不會對堆進行壓縮。當收集器回收時,它會把相鄰的空間進行合并,這樣可以配置設定給較大的對象。但是,當堆空間較小時,運作一段時間以後,就會出現“碎片”,如果并發收集器找不到足夠的空間,那麼并發收集器将會停止,然後使用傳統的标記、清除方式進行回收。如果出現“碎片”,可能需要進行如下配置:

     1. -xx:+usecmscompactatfullcollection:使用并發收集器時,開啟對年老代的壓縮。

     2. -xx:cmsfullgcsbeforecompaction=0:上面配置開啟的情況下,這裡設定多少次full gc後,對年老代進行壓縮。

垃圾回收的瓶頸

       傳統分代垃圾回收方式,已經在一定程度上把垃圾回收給應用帶來的負擔降到了最小,把應用的吞吐量推到了一個極限。但是它無法解決的一個問題,就是full gc 所帶來的應用暫停。在一些對實時性要求很高的應用場景下,gc暫停所帶來的請求堆積和請求失敗是無法接受的。這類應用可能要求請求的傳回時間在幾百甚至幾十毫秒以内,如果分代垃圾回收方式要達到這個名額,隻能把最大堆的設定限制在一個相對較小的範圍内,但是這樣又限制了應用本身的處理能力,同樣也是不可接受的。

       分代垃圾回收方式确實也考慮了實時性要求而提供了并發回收器,支援最大暫停時間的設定,但是受限于分代垃圾回收的記憶體劃分模型,其效果也不是很理想。

       為了達到實時性的要求(其實java語言最初的設計也是在嵌入式系統上的),一種新垃圾回收方式呼之欲出,它既支援短的暫停時間,又支援大的記憶體空間配置設定。可以很好的解決傳統分代方式帶來的問題,參見增量收集,不過目前本人也不會使用,也隻是看到由這個的介紹,但是怎麼用沒有研究過,如果你們研究清楚了歡迎分享。