歲月如哥
          人生非夢
          posts - 50,comments - 144,trackbacks - 0
          原文地址:http://blog.csdn.net/sfdev/archive/2008/01/18/2051171.aspx

          這幾天,網店系統基礎架構進行了一次大的升級,升級之后例行的進行了壓力測試,以前幾次大的項目發布壓力測試都沒有任何問題,沒想到這次出事故啦,而且是內存泄露?

          系統運行環境:
          硬件:Intel(R) Xeon(R) CPU 2.0G、4G RAM、Linux 2.6.9-42.ELsmp #1 SMP
          軟件:jboss-4.0.5.GA [Java HotSpot(TM) Server VM (build 1.5.0_10-b03, mixed mode)]
          JAVA運行參數-server -Xms2048m -Xmx2048m -XX:NewSize=768m -XX:PermSize=128m -XX:MaxPermSize=128m

          現象是這樣的:
          對系統壓力測試大約4個小時左右,系統突然down掉,拋錯為java.lang.OutOfMemoryError: requested 12 bytes for intptr_t in /BUILD_AREA/jdk1.5.0_10/hotspot/src/share/vm/runtime/deoptimization.cpp. Out of swap space?
          由于是晚上進行,所以沒有觀察到任何比較奇怪的現象出現,再次壓力測試,仍然拋錯,但稍微有些不同java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
          經多次壓力,現象100%可以重現;

          解決過程:
          1、use jvmstat first
            這是SUN自己的性能跟蹤工具,他占用server資源很少;監控的結果令我們失望,因為JVM表現完全正常,我們分配的2G內存還有很多剩余,并沒有耗盡;GC也很正常,沒有出現明顯的Full GC或者是每次GC時間太長的情況;
            用top命令查看占用內存不到3G,也還算富裕;而且系統并沒有JNI的使用;為什么會報OutOfMemoryError呢?未果!
          2、search Out of swap space
            更多都是遭遇了相同的問題,但是好像都沒有一個很可行的解決辦法,甚至有人懷疑是JDK的bug,也有人說可以用-Xss參數設置stack size大小,ss默認大小為512k,但是從監控上看我們的進程也沒有那么多,但還是嘗試了一把,再次壓力問題仍然未解決!
          3、try to see heap dump
            添加參數-XX:+HeapDumpOnOutOfMemoryError,讓系統出現OutOfMemoryError時將當時JVM內所有heap dump出來,使用jHAT分析;
            很可惜,1.5中對該參數的支持超級有限,記錄下來的信息很少,并沒有我們想象的那么多,那么有用,基本上這些信息是無用的;再次失敗!
          4、back to OutOfMemoryError
            由于jvmstat 能看見的JVM內部信息有限,所以我們打算用專業工具JProfiler來進行詳查;環境搞定之后,再次壓力,不到2小時情況就重現了,但是從JProfiler中觀察到的信息顯示JVM內部的確沒有任何異常,結論和Jconsole觀察后完全一樣,JVM內部沒有任何問題!但為什么會有此錯誤?想不通……
          5、focus on java heap with linux
            再次search了linux環境下面java heap的相關工作原理及組成信息,有發現了!
            其實java heap由2部分組成:其一為我們熟悉的JVM heap,其二為和OS相關的Native heap;
            JVM heap完全由GC掌控,我們可以通過參數-Xms、-Xmx指定其大小,并且可以用工具對其進行監控;他管理的東西就是我們所有的Java Object;
            而Native heap是平臺相關的,我們既不能設置其使用大小也不能干預他的使用狀態;他管理的東西一般都是很底層的,比如JIT使用的buffer、GC的底層data structures、JNI調用的所有相關對象、SWING/AWT調用需要的buffer和data structures……
            由此想到,是否我們分配的JVM heap太大了,于是設置參數變為-Xms1536m -Xmx1536m再次壓力,問題解決了!!!

          雖然問題解決了,但是我們還是沒能從根本上解釋此次故障,因為系統可用的內存還有很多,并沒有耗盡?
          難道32位的JAVA所能操作的內存只有2G?JVM heap全部占完了會導致Native heap無法allocate memory?后續還需要進一步研究此事;

          PS:
          1、上面我們提到專業級的性能監控工具JProfiler,他的介紹及其安裝使用可以參考http://blog.chinaunix.net/u/11765/showart_239554.html
            有兩點可以注意下;其一:sh安裝方式下linux默認安裝目錄一般為/usr/local/jprofilerX;其二為${JPROFILER_HOME}/bin/linux-x86目錄不一定要放在單獨項LD_LIBRARY_PATH中,只要classpath中能找到即可;
          2、JProfiler、JProbe Profiler、Java Profiler三者是同一個產品么?
            答案當然為否;三者都是業內非常優秀的Java性能監控工具,他們分別屬于不同的公司;
            JProfiler:http://www.ej-technologies.com
            JProbe Profiler:http://www.quest.com;TOAD就是該公司的產品之一;
            Java Profiler:http://www.yourkit.com



          其實現在回過頭來看下這個問題,簡直太easy了,java官方文檔中明確闡述了heap的兩種類別,分別會導致兩類的oom,一類當然是我們非常熟悉的jvm oom,另外一類就是native heap oom;
          這也提醒之后遇到問題時第一時間找的不一定是search,可能官方文檔更有效;
          posted on 2008-09-21 15:14 歲月如歌 閱讀(450) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 麟游县| 洛宁县| 文昌市| 宁河县| 常宁市| 哈密市| 同心县| 江华| 灵台县| 石泉县| 湖北省| 龙岩市| 同心县| 化隆| 泰宁县| 南开区| 方城县| 辉南县| 商城县| 镇宁| 太康县| 南和县| 汝州市| 鄯善县| 五台县| 宜州市| 横山县| 翼城县| 磴口县| 彭泽县| 栖霞市| 贵港市| 晴隆县| 库尔勒市| 盐山县| 承德市| 祁连县| 通江县| 淮南市| 怀柔区| 楚雄市|