JVM性能調優

1、JVM內存模型java

 1.根據Java虛擬機規範,JVM將內存劃分爲:緩存

  • New(年輕代)
  • Tenured(年老代)
  • 永久代(Perm)

  其中New和Tenured屬於堆內存,堆內存會從JVM啓動參數(-Xmx:3G)指定的內存中分配,Perm不屬於堆內存,有虛擬機直接分配,但能夠經過-XX:PermSize -XX:MaxPermSize 等參數調整其大小。性能

  • 年輕代(New):年輕代用來存放JVM剛分配的Java對象
  • 年老代(Tenured):年輕代中通過垃圾回收沒有回收掉的對象將被Copy到年老代
  • 永久代(Perm):永久代存放Class、Method元信息,其大小跟項目的規模、類、方法的量有關,通常設置爲128M就足夠,設置原則是預留30%的空間。

New又分爲幾個部分:.net

  • Eden:Eden用來存放JVM剛分配的對象
  • Survivor1
  • Survivro2:兩個Survivor空間同樣大,當Eden中的對象通過垃圾回收沒有被回收掉時,會在兩個Survivor之間來回Copy,當知足某個條件,好比Copy次數,就會被Copy到Tenured。顯然,Survivor只是增長了對象在年輕代中的逗留時間,增長了被垃圾回收的可能性。

2、JVM調優方案對象

    在JVM啓動參數中,能夠設置跟內存、垃圾回收相關的一些參數設置,默認狀況不作任何設置JVM會工做的很好,但對一些配置很好的Server和具體的應用必須仔細調優才能得到最佳性能。經過設置咱們但願達到一些目標:生命週期

  • GC的時間足夠的小
  • GC的次數足夠的少
  • 發生Full GC的週期足夠的長

  前兩個目前是相悖的,要想GC時間小必需要一個更小的堆,要保證GC次數足夠少,必須保證一個更大的堆,咱們只能取其平衡。內存

   (1)針對JVM堆的設置,通常能夠經過-Xms -Xmx限定其最小、最大值,爲了防止垃圾收集器在最小、最大之間收縮堆而產生額外的時間,咱們一般把最大、最小設置爲相同的值
   (2)年輕代和年老代將根據默認的比例(1:2)分配堆內存,能夠經過調整兩者之間的比率NewRadio來調整兩者之間的大小,也能夠針對回收代,好比年輕代,經過 -XX:newSize -XX:MaxNewSize來設置其絕對大小。一樣,爲了防止年輕代的堆收縮,咱們一般會把-XX:newSize -XX:MaxNewSize設置爲一樣大小get

   (3)年輕代和年老代設置多大才算合理?這個我問題毫無疑問是沒有答案的,不然也就不會有調優。咱們觀察一下兩者大小變化有哪些影響虛擬機

  • 更大的年輕代必然致使更小的年老代,大的年輕代會延長普通GC的週期,但會增長每次GC的時間;小的年老代會致使更頻繁的Full GC
  • 更小的年輕代必然致使更大年老代,小的年輕代會致使普通GC很頻繁,但每次的GC時間會更短;大的年老代會減小Full GC的頻率
  • 如何選擇應該依賴應用程序對象生命週期的分佈狀況:若是應用存在大量的臨時對象,應該選擇更大的年輕代;若是存在相對較多的持久對象,年老代應該適當增大。但不少應用都沒有這樣明顯的特性,在抉擇時應該根據如下兩點:(A)本着Full GC儘可能少的原則,讓年老代儘可能緩存經常使用對象,JVM的默認比例1:2也是這個道理 (B)經過觀察應用一段時間,看其餘在峯值時年老代會佔多少內存,在不影響Full GC的前提下,根據實際狀況加大年輕代,好比能夠把比例控制在1:1。但應該給年老代至少預留1/3的增加空間