成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

讓人頭疼的WAS內存溢出,看銀行運維人員如何優雅的解決

新聞 系統運維
在日常的生產運維中,WAS應用問題的排查確實讓筆者這種銀行運維人員頭疼。

 [[313156]]

1 引言

WAS(IBM WebSphere Application Server)是IBM發布的一款成熟的企業級Web中間件產品,憑借其可靠性與穩定性,一直是國內大型商業銀行Web服務的主流選擇??稍俜€定也會出問題,在日常的生產運維中,WAS應用問題的排查確實讓筆者這種銀行運維人員頭疼。一方面廠商提供技術支持的時效性與準確性有待改善,另一方面像IBM其他產品一樣,網上開放的可參考和借鑒的資料太少,發生WAS問題時著實讓人無從下手。不過不要緊,魯迅先生曾經說過,“走的人多了,自然就有路了”,筆者作為具有多年WAS運維經驗的老鳥,下面就把自己在應對WAS內存溢出方面的知識總結一下,為大家介紹一下如何優雅的應對WAS內存溢出。

2 IBM JAVA內存管理

要應對WAS內存溢出,必須對IBM對JAVA內存的管理有所了解,下面,筆者就簡單介紹一下IBM是如何管理JAVA內存的。不同于大家經常使用的Oracle Java,WAS使用的JAVA是內置于WAS內部的IBM JAVA,與Oracle Java在JVM、配置參數等方面有著顯著不同。

 

IBM JAVA 同樣包含JDK、JRE、JVM三層,其關系如圖所示:

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖1 JDK、JRE、JVM關系

 

JVM內存管理區域包括程序計數器、Java虛擬機棧、堆空間、方法區、運行時常量池、本地方法棧(The Java® Virtual Machine Specification Java SE 8 Edition定義的內存區域)。以上幾個內存區域中,除程序計數器區域外,都可能會產生OutOfMemoryError錯誤(本文中內存溢出特指Java的“OutOfMemoryError”)。

 

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖2 JVM 運行時內存區域

程序計數器區域
Java虛擬機支持多線程運行,所以對于每個線程,都需要一個指示其運行程序位置的指針,這個指針指向當前程序運行方法的地址。

Java虛擬機棧
每一個Java線程都擁有一個私有的Java虛擬機棧。像其他傳統語言一樣,Java虛擬機棧保存了程序調用時的局部變量和部分結果(稱之為Frame)。

方法區、運行時常量池
方法區存放運行時常量池、字段以及方法(包括構造方法、特殊方法)代碼。在IBM Java 8版本中,所有加載的類都存放在稱之為Metaspace的空間中,Metaspace使用操作系統本地內存空間。

本地方法區域
為了支持操作系統本地方法(如C語言)調用,虛擬機中在本地方法區域中存儲本地方法調用的棧信息。

堆空間
堆是JVM運行時內存中最大的區域,也是和程序開發密切相關區域,所有的對象實例(包括基本類型)、數組都存放在這個區域。和傳統的C、C++語言不同,Java語言不需要開發人員顯式地進行內存的申請和釋放,而是由JVM的Allocator(內存分配器)和Garbage Collection(內存垃圾回收器,簡稱GC)負責管理內存。我們最常見的內存溢出“java.lang.OutOfMemoryError : Java heap space”也主要和該區域有關。下面我們將著重闡述IBM J9 VM堆空間相關模型和垃圾回收策略。

堆空間內存結構和垃圾回收策略(GC)
J9 VM支持多種不同的GC策略,不同的GC策略對應不同的Heap內存模型及分配回收算法,不同的GC策略適應于不同的業務場景,對于大多數系統(特別是交易類系統)來說,可使用“Generational Concurrent Garbage Collector”策略(簡稱gencon,參數:-Xgcpolicy:gencon可以指定使用該策略),這也是J9 VM的默認GC策略,本文主要詳細介紹該策略。

“Generational Concurrent Garbage Collector”策略特別適合存在非常多短生命周期對象的應用,即對象申請完之后,很快就不被使用,可以被GC回收。而一般的交易類系統,都符合這種場景。

在該策略下,Heap內存被劃分成新區域(Nursery)、老區域(Tenured)。所有對象創建后都被分配到Nursery區域,之后如果該對象一直標記為可用,則會被自動到Tenured區域。

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖3 J9 VM 默認堆空間內存模型

 

更進一步,可以將Nursery區域劃分為Allocate空間、Survivor空間。新創建的對象一開始被分配到Allocate空間,當Allocate空間滿之后,觸發一次Local GC,由Scavenge 進程將Allocate空間中“活著的”對象拷貝到Survivor區,超過一定周期(Tenured age)的對象則直接被移動到Tenured區域。之后,Allocate空間、Survivor空間的角色互換,等待下次Local GC。

 

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖4 Local GC過程

上文提到,在一般場景下,大部分對象創建后,很快就不被使用、存活的對象較少,所以Local GC移動的數據也很少,而且Local GC后,可以得到很大的Allocate空間,這樣就減小了GC時間。在JVM中,GC意味著所有運行中線程都要停下來(Pause)等待GC結束,GC完成后,才可以繼續運行,所以Local GC可以減少因GC帶來的系統吞吐量下降的影響。

發生堆空間分配失敗或者調用System.gc()方法后,觸發Global GC過程。Global GC通過標記、清除、壓縮過程來盡可能釋放JVM內存空間。Global GC需要獲得整個JVM的排他控制權,所以當進行Global GC時,所有應用線程也將暫停。當Global GC結束后,應用線程將恢復執行。

3 常見的WAS內存溢出原因

上面我們介紹了IBM Java內存管理的模型和策略。理解上述模型后,我們可以清楚的知道為何會發生內存溢出:

(1)JVM內部或者JVM間接使用的操作系統內存分配失敗后觸發內存溢出報錯。JVM內存區域中,除了程序計數器區域外,Java虛擬機棧、堆空間、方法區、運行時常量池、本地方法棧都可能會發生內存溢出報錯。

(2)對于堆空間,當堆空間已經盡可能擴展,并且JVM花費了95%以上的時間在GC時,也會觸發內存溢出報錯。

以上兩點是內存溢出的基本要點,但實際生產系統由于運行環境往往較為復雜,在處理實際問題時,我們還應結合環境配置和業務場景來分析。通過總結實際運維過程中經驗,可以將內存溢出原因分為如下幾類:

(1)堆內存大小上限配置過低
由于Java程序所能使用的堆空間上限完全取決于JVM啟動時的參數配置,當堆空間上限參數設置過低,即使操作系統物理內存空閑較多,應用程序也無法使用。所以在問題排查時,我們首先應該明確系統配置的堆空間上限(由Xmx參數指定),一般不能使用堆大小上限默認值。

(2)程序內存泄漏導致內存持續增長
如果程序存在內存泄漏,即使已經不再使用的內存仍將無法被GC回收釋放,JVM內存將持續增長(而且,由于內存使用率逐漸升高,將會更加頻繁的觸發GC,反復GC又會引發CPU過高),最終導致堆內存空間滿而引發內存溢出。

(3)數據查詢交易返回記錄數過多或者程序申請使用大內存對象
當程序過度地使用內存大對象或數組,導致無法申請足夠的內存空間而引發內存溢出。例如,在實際生產中,可能存在應用程序讀取整表數據或情況(數據條數在幾萬條以上),極易引發內存溢出。

(4)物理內存過低或因其他進程消耗過多內存引發內存溢出
即使我們設定了合理的JVM內存空間大小上限,但也有可能因為本地操作系統本身可用內存過低、無法實現內存空間的動態擴充,進而導致內存溢出;也可能因為在同一個操作系統上運行的其他JVM或者本地進程使用過多的內存導致內存溢出;由于JVM的部分區域(如Metaspace、DirectMemory等)直接使用的是操作系統內存,所以當操作系統內存過低,但創建本地線程過多、加載類過多時也有可能發生內存溢出異常;當程序過度使用DirectMemory也會引發內存溢出。

(5)交易量突然增大
如果我們將JVM堆內存上限設為M,每支交易處理需要使用的堆內存是N,那么當同時處理的交易量X突然增多N*X>M時,就容易觸發內存溢出。

4 如何優雅的應對WAS內存溢出

當發生內存溢出后,首先要做的是恢復生產,恢復因內存溢出而宕機的Server?;謴蜕a后,可按照下面步驟進行內存溢出原因分析。

收集環境信息
內存溢出分析首先要做的就是收集環境信息和日志信息。

收集日志文件

表 1 收集日志文件表
讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

分析應用日志
查看SystemOut.log日志java.lang.OutOfMemoryError的提示信息,確定內存溢出發生在JVM的哪個區域之后,查看SystemOut.log、SystemErr.log中應用交易日志,分析是否可疑的異常交易。

分析堆內存使用趨勢
一般內存分析,第一步先查看JVM內存使用情況,即通過“IBM Pattern Modeling and Analysis Tool for Java Garbage Collector”工具,打開native_stderr.log文件,查看JVM堆空間內存使用曲線:

對于大對象或數組使用導致內存溢出的曲線一般如下圖所示,存在曲線突然升高的情況:

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖5 大對象內存溢出堆空間趨勢圖

內存泄漏導致內存溢出的曲線一般如下圖所示,曲線緩慢上升(紅色曲線):

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖6 內存泄漏程序堆空間趨勢圖

找到堆空間可疑內存溢出點

 

使用IBM HeapAnalyzer工具分析Heapdump文件。HeapAnalyzer工具列出了可疑的內存溢出點,分析人員需要逐個對這些可疑點進行排查,結合程序代碼進行進一步確認。

 

分析線程現場信息
使用“IBM Thread and Monitor Dump Analyzer for Java”工具,分析javacore文件。檢查內存溢出時正在執行的交易、正在執行的方法。

非堆空間內存溢出
如果出現“java.lang.OutOfMemoryError: 本機內存耗盡”內存溢出報錯,則需要考慮DirectByteBuffer內存區域引發內存溢出。

5 如何在具體場景應用

 

上面白話了那么多,想必各位已經頭暈眼花,那么接下來就來點干貨。在具體的運維場景中,銀行運維人員該如何快速分析和定位WAS內存溢出的問題呢,讓筆者來結合自己遇到的某個實際場景進行闡述。
某次筆者正在優雅的喝著咖啡,寫著工作總結,忽然接到監控告警通知,“XX管理系統交易超時率提高,請盡快處置”。筆者一陣激靈,趕快扔下咖啡跑進操作間開始排查系統問題。
第一步,當然是盡快恢復生產嘍,筆者排查時,通過監控發現某臺WAS服務器內存直沖天際,隱隱有突破內存限制的隱患,而就在同時,交易超時的情況開始同時升高。基本已經能定位問題是由于內存原因導致的,那么為了盡快恢復生產,筆者當然是首先選擇對故障服務器的WAS應用進行了重啟。

 

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖7:發生問題時某臺WAS服務器的內存監控情況

 

第二步,重啟大法果然不出意外的解決了問題,重啟WAS應用后系統交易超時指標恢復了正常。接下來,筆者就要認真排查問題,到底是什么導致了這次內存意外的沖高呢。筆者開始著手采集分析文件,主要包括SystemOut.log(輸出日志)、SystemErr.log(錯誤日志)、native_stderr.log(GC日志),在采集時,筆者還在日志目錄中發現了Javacore文件與Heapdump文件,這已經能確認是發生了內存溢出,下面的問題就是分析原因了。

 

第三步,首先我們來查看日志文件,下面分別是SystemOut.log和SystemErr.log的部分內容。果然,在問題時點附近的錯誤日志中看到了OutOfMemoryError,同時在應用日志中看到了一些正在執行的sql,那么到底是哪個程序在作怪,又是為什么產生了內存溢出呢。

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖8:問題時點的應用日志

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖9:問題時點的錯誤日志

第四步,看來僅從日志是無法定位具體問題的,筆者接下來要運用工具來解決問題了。筆者先后用IBM HeapAnalyzer和IBM Thread and Monitor Dump Analyzer for Java工具,分別對Heapdump文件及Javacore文件進行了具體的分析。對Heapdump文件的解析結果顯示,某個List居然存在68萬多個對象,占用了近50%的內存空間。對Javacore文件的分析結果顯示,發生溢出時某支交易線程一直處于等待狀態。

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖10:Heapdump文件的分析結果

讓人頭疼的WAS內存溢出,銀行運維人員該如何優雅的解決

圖11:Heapdump文件的分析結果

 

第五步,有了這么豐富的信息,筆者已經做出了基本的判斷,本次WAS內存溢出應該是由于某線程在一次查詢時獲取了太多數據,導致JVM為裝載這些數據的List對象分配了過多內存,從而導致的內存溢出。筆者將信息反饋給開發人員后,果然沒多久就得到確認,確實是某條查詢語句未對查詢結果進行分頁處理,一次性命中過多查詢結果后將其全部裝入內存導致。
至此,筆者的這次應急處置與事件分析工作告了一段落,筆者心滿意足的回到工位,繼續開始喝咖啡,寫總結,優雅的等待下班的到來,相信開發人員修復這個隱藏缺陷后,筆者又可以清凈一段時間了。

 

6 如何預防或解決內存溢出問題

 

經過上面一番講解,相信對于WAS內存溢出的分析,無論是理論還是實踐大家都有了一定的認識,那么,我們如何能預防或避免這種問題呢。筆者進行了一些簡答的總結。
對于物理內存不足或者堆空間上限配置不足的情況,需要評估合適的物理內存或者堆空間上限大小,進行擴充。需要注意的是32位WAS最大堆內存上限為1536MB,如果需要升級到更大內存,則需要遷移到64位WAS平臺。另外,堆內存空間并不是越大越好,越大的內存意味著GC管理也越復雜,GC的耗時及應用程序停頓的時間也越長。
對于存在內存泄漏或者是大對象申請情況引發的內存溢出,一般需要在定位問題原因后,在測試環境復現問題,進行程序優化解決問題。程序優化的方法不一而足,例如存在大數據量數據查詢的情況可以加入篩選條件或者增加分頁處理;也可以暫時規避解決的方式,通過關閉發生問題的交易或者修改交易流程不觸發內存溢出的場景來臨時性解決問題。

 

7 最后

 

以上就是筆者總結的如何優雅的應對WAS內存溢出的全部內容了,WAS作為一款企業級Web中間件,至少目前在國內銀行、證券等大型國企中還占據著主導地位,了解WAS知識有助于我們在生產運維過程中高效解決問題,提高應急處置效率,后續筆者會繼續總結在日常運維過程中碰到的問題,跟大家共同分享和交流。

 

 

 

責任編輯:張燕妮 來源: 高效運維
相關推薦

2021-10-09 09:47:14

Java開發 bug

2017-10-20 12:00:36

Python全局解釋器鎖GIL

2023-04-19 09:05:44

2017-12-12 13:27:20

主板跳線USB

2019-07-03 15:01:30

戴爾

2024-09-09 09:41:03

內存溢出golang開發者

2017-07-14 14:52:25

MySQLAborted告警案例分析

2020-11-30 14:40:52

事務系統項目

2010-04-08 13:17:39

IT管理系統遷移賽門鐵克

2010-11-16 09:07:32

2009-06-16 11:01:14

Java內存溢出

2022-05-19 12:14:22

分布式開發框架

2021-11-15 06:56:45

系統運行空指針

2012-03-14 10:58:27

Java

2019-01-08 08:50:56

2009-12-08 15:37:39

2021-06-28 06:45:06

內存溢出內存泄露JavaScript

2021-12-06 09:57:25

容器Linux信號

2021-05-09 22:26:36

Python函數變量

2012-05-15 02:04:22

JVMJava
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本福利视频免费观看 | 久久综合色综合 | 欧美日韩国产一区二区三区 | 欧美日韩成人 | 久久不射电影网 | 中文字幕日韩欧美一区二区三区 | 午夜视频在线观看网站 | 国产精品一区二区三区在线 | 久久久久久国产精品三区 | 精品videossex高潮汇编 | 91 中文字幕 | 国产在线网站 | 九九久久久久久 | 久在线视频 | www四虎影视 | 欧美一级淫片免费视频黄 | 日韩人体在线 | 久久久天天| 亚洲精品久久久久久宅男 | 亚洲成人一级 | 欧美日韩一卡 | 欧美黄色一区 | 久久一区二区av | 国产精品美女久久久久久不卡 | 黄色大片在线 | 亚洲欧美自拍偷拍视频 | 亚洲二区视频 | 涩涩视频网站在线观看 | 久草青青草 | 色综合99 | 成人在线视频网 | 日本不卡在线视频 | 日日噜噜噜夜夜爽爽狠狠视频, | 亚洲色视频 | 99久久精品一区二区成人 | 日本一道本 | 完全免费在线视频 | 九九热精品视频 | 毛片免费观看 | 欧美综合在线视频 | 一级做a爰片久久毛片 |