有關應用服務器不穩定與內存泄漏問題

問題描述

1. 應用服務器內存長期不合理佔用,內存經常處於高位佔用,很難回收到低位;

2. 應用服務器極爲不穩定,幾乎每兩天重新啓動一次,有時甚至每天重新啓動一次;

3. 應用服務器經常做Full GC(Garbage Collection),而且時間很長,大約需要30-40秒,應用服務器在做Full GC的時候是不響應客戶的交易請求的,非常影響系統性能。

內存長期佔用並導致系統不穩定一般有兩種可能:

1. 對象被大量創建而且被緩存,在舊的對象釋放前又有大量新的對象被創建使得內存長期高位佔用。

  • 表現爲:內存不斷被消耗、在高位時也很難迴歸到低位,有大量的對象在不斷的創建,經過很長時間後又被回收。例如:在HttpSession中保存了大量的分頁查詢數據,而HttpSession的會話超時時間設置過長(例如:1天),那麼在舊的對象釋放前又有大量新的對象在第二天產生。
  • 解決辦法:對共享的對象可以採用池機制進行緩存,避免各自創建;緩存的臨時對象應該及時釋放;另一種辦法是擴大系統的內存容量。

2. 另一種情況就是內存泄漏問題

  • 表現爲:內存回收低位點不斷升高(以每次內存回收的最低點連成一條直線,那麼它是一條上升線);內存回收的頻率也越來越高,內存佔用也越來越高,最終出現"Out of Memory Exception"的系統異常。
  • 解決辦法:定位那些有內存泄漏的類或對象並修改完善這些類以避免內存泄漏。方法是:經過一段時間的測試、監控,如果某個類的對象數目屢創新高,即使在JVM Full GC後仍然數目降不下來,這些對象基本上是屬於內存泄漏的對象了。

問題定位&解決方法

         JProbe Profiler對內存進行實時監控。Session和各種全局變量中引用的無用對象。關於java的內存泄漏的JVM級技術原因在下面這篇文章中有介紹:

什麼是Java中的內存泄露

下面,我們就可以描述什麼是內存泄漏。在Java中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連;其次,這些對象是無用的,即程序以後不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定爲Java中的內存泄漏,這些對象不會被GC所回收,然而它卻佔用內存。

C++中,內存泄漏的範圍更大一些。有些對象被分配了內存空間,然後卻不可達,由於C++中沒有GC,這些內存將永遠收不回來。在Java中,這些不可達的對象都由GC負責回收,因此程序員不需要考慮這部分的內存泄露。

通過分析,我們得知,對於C++,程序員需要自己管理邊和頂點,而對於Java程序員只需要管理邊就可以了(不需要管理頂點的釋放)。通過這種方式,Java提高了編程的效率。


因此,通過以上分析,我們知道在Java中也有內存泄漏,但範圍比C++要小一些。因爲Java從語言上保證,任何對象都是可達的,所有的不可達對象都由GC管理。 

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