BlackHole開發日記-一次壓力測試及JVM調優的通過

BlackHole開發好久了,目前穩定性、性能都還能夠了,可是做爲一個Java程序,內存開銷一直是硬傷,動不動100M內存下去了,對於單機用戶實在是不太友好。java

怎麼辦?優化先從分析開始!web

獲取內存信息

獲取內存信息通常使用jmap。數組

jmap -histo pid

這種方式獲取到得比較簡略,咱們能夠先把內存dump下來,再進行離線分析。jhat是一個離線內存分析工具,會開啓一個web服務以供展現。jvm

jmap -dump:file=dumpfile pid
jhat -J-Xmx512m dumpfile

訪問 http://127.0.0.1:7000 便可。默認是Class列表,翻到頁面底部能夠查看其餘功能。工具

參考資料:oop

http://www.lhelper.org/newblog/?tag=jhat性能

http://blog.csdn.net/gtuu0123/article/details/6039474測試

詳細分析

如下分析僅針對JDK 7 HotSpot虛擬機。jmap -histo的結果:優化

num     #instances         #bytes  class name
----------------------------------------------
 1:         28490        4057072  <constMethodKlass>
 2:         28490        3882464  <methodKlass>
 3:          2630        2820064  <constantPoolKlass>
 4:         46350        2412600  <symbolKlass>
 5:         32778        2372824  [C
 6:          2630        1990744  <instanceKlassKlass>
 7:          3418        1955208  [I
 8:         15491        1911568  [B
 9:          2347        1845400  <constantPoolCacheKlass>
10:         19246         615872  java.lang.String
11:           256         561152  [Lnet.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry;
12:          2930         304720  java.lang.Class
13:          3740         247280  [S
14:          4321         221520  [[I

其中[開頭表示數組,[C [I [B 分別是char[] int[] byte[]。.net

constMethodKlass、都實現自sun.jvm.hotspot.oops.Klass,用於在永久代裏保存類的信息。

換到JDK6以後,發現永久代的消耗下去了。

num     #instances         #bytes  class name
----------------------------------------------
 1:         10823        3072312  [B
 2:         16605        2318720  <constMethodKlass>
 3:         18687        1388088  [C
 4:         16605        1328608  <methodKlass>
 5:         27595        1296832  <symbolKlass>
 6:          1699         940392  <constantPoolKlass>
 7:          2520         883408  [I
 8:          1699         724944  <instanceKlassKlass>
 9:          1472         565136  <constantPoolCacheKlass>
10:           256         561152  [Lnet.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry;
11:         12148         291552  java.lang.String
12:          4505         288320  net.sf.ehcache.Element
13:          7290         233280  java.lang.ThreadLocal$ThreadLocalMap$Entry
14:          1946         186816  java.lang.Class
15:          4509         180360  net.sf.ehcache.store.chm.SelectableConcurrentHashMap$HashEntry

查看一下總的內存開銷(參考資料: http://yytian.blog.51cto.com/535845/574527)

ps -e -o 'pid,comm,args,pcpu,rsz' | grep java |  sort -nrk5
1239 java            java -jar -Djava.io.tmpdir=  0.1 52816

或者:

top -pid pid

查看到只有52m,看來JDK7佔用內存果真增長了!

壓力測試

使用140,000個隨機域名作壓力測試。發現以前使用的JDK7 Developer Preview u04,在短期產生大量對象的時候,GC會失去做用,內存迅速飆升到200M,後來更新到1.7.0u25,穩定到了130m,qps大概在49000~50000之間。

嘗試使用ConcurrentHashMap代替EhCache,qps提升到50000~51000之間,變化不明顯,EhCache仍是至關優秀的。

爲了提升吞吐量,查看GC狀況:

sudo jstat -gcutil 2960
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
0.00   0.75  30.35  12.06  72.92     25    0.063     0    0.000    0.063

140,000個請求產生了25次YGC。

參考了關於JVM的調優文章http://blog.csdn.net/kthq/article/details/8618052

從新設置新生代爲200m,並開啓並行收集:

JVM_OPTION="-XX:+UseParallelGC -XX:NewSize=200m"

140,000個請求只產生了3次YGC,可是qps變化並不明顯。看來新生代設置大以後,雖然YGC少了,可是一次回收的時間多了,最終其實沒啥影響啊,那仍是弄小一點好了。

看來折騰JVM效果不明顯,除了內存開銷以外,其餘沒有明顯變化。

相關文章
相關標籤/搜索