性能測試中,CPU和內存是關注最多的兩個性能指標。以我行應用最多的系統架構(WAS+Oracle)來講,CPU使用率高的問題多發生於數據庫,好比索引不當引起的表掃描、綁定變量使用不當引起的硬解析、鏈接池使用不當引起的頻繁創建斷開鏈接,這些都會致使數據庫服務器CPU使用率高。java
內存問題則多發生於應用服務器。部署在WAS平臺的Java應用,常常發生的問題是JVM堆內存溢出。產生該問題的緣由有不少:數據庫
·由環境引起的,虛擬機物理內存不足;服務器
·由參數配置引起的,JVM堆內存設置太小;session
·由應用程序引起的,內存泄露,錯誤使用大對象等等。架構
在實際性能測試過程當中選擇監控指標時,對JVM堆內存的監控分析比對操做系統內存的分析更爲重要。JVM堆內存溢出的緣由中,虛擬機物理內存不足經常被忽視。本文結合項目測試過程當中發現的由內存不足引起的性能問題,設計幾個場景來探索JVM堆內存和虛擬機內存之間的影響關係。性能
1、測試
莫名其妙的「會話超時」spa
在某交易(登陸+查詢+退出)的疲勞場景中,發現應用服務器內存使用率超過90%,且被測交易存在大量報錯:用戶未登陸或已超時,請登陸。WAS中會話相關的兩個參數,最大內存中會話數1000和會話超時30分鐘。性能測試場景中,會話數使用不到1000,且登陸以後並無退出,也不會發生用戶未登陸或已超時。因此,報錯的緣由在哪裏?操作系統
WAS的JVM堆內存和操做系統內存狀態如圖所示。線程
能夠看到,JVM堆內存的分配達到最大值3G,堆實際使用值在到達3G時發生GC,循環如是。JVM堆內存未發生內存溢出,沒有生成heapdump、javacore文件,Server沒有重啓。操做系統內存使用已達92%,且Swap空間使用了1G左右。
Swap分區一般被稱爲交換分區,這是一塊特殊的磁盤空間,當實際內存不夠用的時候,操做系統會從內存中取出一部分暫時不用的數據,放在交換分區中,從而爲當前運行的程序騰出足夠的內存空間。也就是說,當操做系統開始使用Swap空間時,就意味着內存不夠。同時,因爲Swap分區是磁盤空間,使用Swap分區會頻繁讀寫磁盤,這會顯著下降操做系統的運行速度。
根據以上分析,初步判斷,虛擬機內存不足,使用到Swap分區。若是session信息被從內存交換到Swap分區,那這段時間該線程的查詢請求,沒法驗證到session,就會報「用戶未登陸或已超時,請登陸」,交易失敗;若是session信息又被從Swap交換至內存,又不報錯,交易成功。下面經過一些實驗來驗證這一推測。
2、
揭開內存的神祕面紗
首先,咱們看一下測試環境和生產環境的資源配置。能夠看出測試環境單臺虛擬機的配置(CPU內存)是生產環境的1/2,這也是內存不足的根源,下面圍繞內存設計三個場景的測試。
場景一:疲勞測試發生問題的場景。
JVM堆內存GC正常,虛擬機內存不足,使用了Swap分區。爲了進一步肯定Swap分區確實是被WAS使用 ,咱們進入到/proc下WAS Server進程的目錄,cd /proc/${WasServerPid},該目錄下的smaps文件詳細記錄了該進程的內存使用狀況,而後執行cat smaps | grep Swap | grep -v "0 kB" | sort -nr,即可查看進程對Swap的使用。經過查看,該WAS節點的Server1使用了538MB,Server2使用了574MB,加起來1G左右,這與此前監控的結果相符。而重啓Server時,這兩個值都是0,即未使用Swap分區。
場景二:每一個節點只保留1個Server,JVM堆內存最大值爲3G,虛擬機8G內存對於單Server徹底夠用。
測試過程當中,交易總體運行平穩,沒有報錯。JVM堆的分配值也是到達3G,而後經過GC循環使用。但因爲只啓動了一個Server,內存夠用,沒有使用到Swap分區,而且存在必定的富餘。WAS的JVM堆內存和操做系統內存狀態如圖所示。