GC優化過程

GC優化的意義

Java程序的垃圾回收由虛擬機自動進行。通常垃圾回收的時間只佔程序總運行時間的一小部分,所以通常優化程序優先考慮的並不是GC優化,但是在某些比較特殊的情況下,程序運行的過程中,創建了很多臨時變量,短時間內內存佔用過高,這時GC對程序的影響便比較明顯。而且,瞭解GC優化還有助於對Java虛擬機內存模型的理解。

GC優化的目標

軟件構造課程提出:

A best practice is to tune the time spent doing garbage collection to within 5% of execution time. 最佳做法是將GC時間控制在執行時間 的5%之內。

GC分爲Minor GC和Full GC。Minor GC是對年輕代的垃圾回收,它的特點是頻率高,速度快;Full GC是對老年代和永久代(JDK8以後變成元數據區)的垃圾回收,它的特點是頻率低,速度慢。GC優化的目標是讓兩者的時間相加最小。

GC優化的方法

  1. Specifying VM heap size  指定虛擬機堆的大小
  2. Choosing a garbage collection scheme 選擇合適垃圾回收器
  3. Using verbose garbage collection to determine heap size
  4. Automatically logging low memory conditions
  5. Manually requesting garbage collection
  6. Requesting thread stacks

通常GC優化指的就是分析GC日誌並測試找到合適的虛擬機堆設置和指定合適的垃圾回收器。

An acceptable rate for garbage collection is application-specific and should be adjusted after analyzing the actual time and frequency of garbage collections.
If you set a large heap size, full garbage collection is slower, but it occurs less frequently.
If you set your heap size in accordance with your memory needs, full garbage collection is faster, but occurs more frequently.

但是這裏存在一個矛盾是:如果使用比較大的堆,Full的頻率會減小,但是單次Full GC的時間會增加,總的時間不一定減少。所以GC優化需要不斷調整堆的大小,找到最合適的設置。

GC優化過程

測試的程序爲一個圖應用,讀取文本文件中的數據並建圖,文件中包含3000個頂點和將近40萬條邊。在關閉日誌的情況下,程序執行時間約爲8.8s。

使用Java虛擬機默認設置時,GC的情況如下:可以看到進行了24次Minor GC和2次Full GC,GC的時間佔了程序總運行時間將近10%,應當進行適當的優化。

從VisualVM監控結果上可以看到,使用的內存在經過一次比較大的垃圾回收活動後穩定在250m左右,所以從256m開始設置。


  1. -Xms256m -Xmx512m

    使用jstat查看垃圾回收情況:從圖上看,Full GC減少了一次,Minor GC出現次數比比默認設置多。由於Minor GC的總時間增加了很多,而Full GC時間並沒有減少多少,總的GC時間比默認設置高了14%,說明堆的設置還不夠理想。

  1. -Xms512m -Xmx512m

    使用jstat查看垃圾回收情況:從圖上看,沒有Full GC,Minor GC次數爲原來的兩倍多,但是每次gc的時間比默認設置的gc時間少了50%~75%。這種情況意味着大部分變量在年輕代就被銷燬了,沒有轉移到老年代。GC時間比上一種設置少了一半,是比較理想的設置。

  1. -Xms512m -Xmx1024m

    使用jstat查看垃圾回收情況:與上一種設置的結果較爲相似,沒有Full GC,Minor GC次數減少了不少,但是總的時間並沒有減少,而且這種設置會使用較多的空間,所以還是第二種設置較爲合適。

  1. -Xms512m -Xmx512m -XX:+UseParallelGC

    這一次在第二種設置的基礎上增加對垃圾回收器的設置可以看到,垃圾回收的時間進一步降低,說明ParallelGC比默認的垃圾回收器執行速度更快。優化到此,垃圾回收活動的時間已經降低到程序總運行時間的5%以內,基本實現GC優化的目標。

當然這個例子因爲避免了Full GC而使程序的GC時間得到優化,在更大型的程序中,Full GC可能是不可避免的,這就要做更多次的測試,在Full GC次數和Full GC時間之間找到一個最優的方案。

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