關於中間件內存(緩存)溢出的情況分析及解決辦法

因為系統運行時間過程中,weblogic內存中積累了過量的垃圾文件,導致jta資源不足、jdbc找不到連接資源,最後系統崩潰,無法運行。

後台會有如下顯示:

類似於這樣的錯誤,可以通過修改C:\\bea\\weblogic81\\common\\bin\\commEnv.cmd 這個腳本文件。修改內容如下:

goto continue :bea

if \set JAVA_VM=-jrockit

set MEM_ARGS=-Xms128m -Xmx512m

set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none goto continue

:bea_prod_mode

set JAVA_VM=-jrockit

set MEM_ARGS=-Xms256m -Xmx512m goto continue 修改為: goto continue :bea

if \set JAVA_VM=-jrockit

set MEM_ARGS=-Xms768m -Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC

set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none goto continue :bea_prod_mode

set JAVA_VM=-jrockit

set MEM_ARGS=-Xms768m -Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC

goto continue

WebLogic用了一段時間之後,偶爾總是會出現OutOfMemory,這對測試環境來說,還只要Restart Server 就可以解決,但是在正式環境上出現可就麻煩大了,因為一Restart Server 所有User就都無法使用系統,所以MEM_ARGS這個參數的設定就很重要。

這是SIT目前的設定,依不同的系統做不同的設定

MEM_ARGS=\-Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC\

提示:以上記得要寫成一行。

Heap Size設定

-Xms 設定一開始的Heap Size。

-Xmx 設定Heap Size的最大值 (最好是不是超過物理內存的80%)。 -XX:NewSize 調整JVM的Young Generation的size大小。

-XX:MaxNewSize 調整JVM的Young Generation的size的最大值。

– Xmn Young Generation的size,NewSize 和 MaxNewSize設定為一樣。 -XX:NewRatio 控制Young generation的比例,如-XX:NewRatio=3表示Young generation與Old generation的比例為1:3,即Young generation佔1/4,Old generation佔3/4。

Young generation又被分成三部分,第一部分Eden,用於生成新的Object。另外兩個部分為Survivor空間,當Eden用完後,會將 Objects複製到\,當SS1空間滿了的時候,再被複制到\,Objects會在Survivor空間不斷的被複制,直到他滿足條件進入Old generation止。

提示:如果將Heap Size設的越大,GC的周期就會拉長,而且每次GC的時間也會越長。

PermGen space

-XX:PermSize 這一部分是用於存放Class和Meta的訊息,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期間對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。

整個內存配置會像這樣

-XX:+DisableExplicitGC 加了這個參數會停止掉WLS或是程序內直接呼叫GC,減少不必要的GC,將GC交由JVM去執行。

Garbage Collection描述:

Garbage Collection分多種等級,0級就是全部的垃圾回收(Full GC),會回收Old generation中的垃圾;1級或以上為部分垃圾回收,只會回收Young中的垃圾,會發生OutOfMemory通常是產生於Old generation或Perm段垃圾回收後,仍然沒有內存空間來存放新的Java 對象的情況。

當一個URL被訪問時,內存的配置過程如下:

  1. JVM會試圖為Java的相關對象在Eden中初始化一塊內存空間 B. 當Eden空間足夠時,內存配置結束。否則到下一步
  2. JVM會試圖釋放在Eden中所有不活躍的對象(這是屬於1或更高級的垃圾回收);釋放後若Eden空間仍然不足以放入新對象,則會試圖將部分Eden中活躍的對象放入Survivor區/OLD區
  3. Survivor區被用來作為Eden及OLD的中間交換區域,當OLD區空間足夠,Survivor區的對象會被移到Old區,否則被保留在Survivor區
  4. 當OLD區空間不足時,JVM會在OLD區進行完全的垃圾收集(0級) F. 完全垃圾收集後,若Survivor及OLD區仍然無法存放從Eden複製過來的部分對象,就會導致JVM無法在Eden區為新的對象配置出內存區塊,產生\的錯誤\

以我的設定為例:

MEM_ARGS=\-Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC\

在上面的例子中: YOUNG+OLD: 768M YOUNG: 256M Perm: 384M

Eden: YOUNG*6/(6+1+1)=192M Survivor: YOUNG*1/(6+1+1)=32M Heap Size: YOUNG+OLD+Perm=1024M

以上是WebLogic內存參數的一些基本的設定,太難的我也不會,只是整理一些心得而己,提供做一下參考

堆( Heap)是 Java 程序的對象生活的地方,包含活的對象,死的對象以及剩餘內存 。 當對象不能被運行中的程序的指針所到達時,這些對象成為”垃圾“。 JVM 的堆大小決定了 VM 花費在收集垃圾上的時間和頻度。 收集垃圾可以接受的速度與應用有關,應該通過分析實際的垃圾收集的時間和頻率來調整。

如果堆的大小很大,那麼完全垃圾收集就會很慢,但是頻度會降低。

如果你把堆的大小和內存的需要一致,完全收集就很快,但是會更加頻繁。 調整堆大小的的目的是最小化垃圾收集的時間,以在特定的時間內最大化處理客戶

的請求。

在基準測試的時候,為保證最好的性能,要把堆的大小設大,保證垃圾收集不在整個基準測試的過程中出現。

堆劃分為兩個區域:新生代和舊生代。

新生代又分為:Eden 和兩片生存空間(survivor spaces)。其中保證有一片空間在任何時間是空的,當垃圾收集發生時, Eden 中的活的對象複製到下一片生存空間,對象就在生存空間之間複製,直到到達最大門限值(老化),然後複製到舊生代。

Eden 是新的對象分配的地方。

很多對象分配以後很快成為垃圾,這些對象稱為具有 \ 對象生存的時間越長,需要的收集時間也越長,因此,收集變慢。

你的應用建立和釋放對象的速度決定了垃圾收集的頻度。因此,在編程時,應注意使用對象的緩衝,而不是新建立對象。

大多數對象在新生代就已經死去,因此你能有效的調整垃圾收集。如果你能安排大多數對象的生存期小於一個收集時間,那麼,垃圾收集是十分高效的。

錯誤的”代“配置會導致頻繁的垃圾收集,影響系統性能。 如果系統花費很多的時間收集垃圾,請減小堆大小。 一次完全的垃圾收集應該不超過 3-5 秒。

一般說來,你應該使用物理內存的 80% 作為堆大小。 在最大工作負荷的時候,監視 WebLogic 的性能。

使用 -verbosegc 選項測量有多少時間和資源用於垃圾收集。 打開垃圾收集的詳細信息輸出以及複位向:

% java -ms64m -mx64m -verbosegc -classpath $CLASSPATH -Dweblogic.domain=mydomain -Dweblogic.Name=clusterServer1 -Djava.security.policy==/bea/weblogic6x/lib/weblogic.policy -Dweblogic.management.server=192.168.0.101:7001 -Dweblogic.management.username=system

-Dweblogic.management.password=systemPassword weblogic.Server >> logfile.txt 在 Solaris 系統上,採用下面的命令: weblogic.Server > server.out 2>&1 Java HotSpot VM 選項

標準的選項在各種平台都已經有介紹:

http://java.sun.com/j2se/1.3/docs/tooldocs/win32/java.html http://java.sun.com/j2se/1.3/docs/tooldocs/solaris/java.html http://java.sun.com/j2se/1.3/docs/tooldocs/linux/java.html

以 -X 開頭的選項都為非標準選項(並不能在所有的 VM 上實現),在後續的版本中可能會不通知而變更。

由於 -XX 選項需要特別的系統權限,因此不建議隨便使用。

在 1.3.0 之前的版本, J2SDK 的 Solaris 版本帶有一個虛擬機的實現叫做 Exact VM(EVM),從 1.3.0 開始這個虛擬機被 Java HotSpot VM 所取代。

Java HotSpot VM 目前認識下面的 -X 選項: -Xincgc 使用訓練 GC

-Xnoincgc 不是用訓練 GC(缺省)

-XX:MaxHeapFreeRatio= 最大堆剩餘百分比(缺省 70) -X:MinHeapFreeRation= 堆最小剩餘百分比(缺省 40)

-Xint 只作解析 (不作 JIT 編譯)

-XX:+UseBoundThreads 綁定用戶級別的線程 (只針對 Solaris)

-Xmn 設置年輕一代的大小( young generation )(只對 1.4)

對象分配在 Eden,並且在這裡死亡,當 Eden 滿時,引起一個小的收集(minor collection),一些生存的對象被移動到舊生代,如果舊生代需要收集,則引起大收集(major collection ),這會比較緩慢。

如果 GC 成為瓶頸,那麼需要指定代的大小,檢查 GC 的詳細輸出,研究 GC 參數對性能的影響。

舊生代的收集採用 mark-compact 的方式,其中的一部分叫做”永久代“(permanent generation)很特別,他包括了 JVM 自身的所有反映數據(reflective data),例如類以及方法。

暫停時間的含義是應用因為垃圾收集而顯示出來的短暫停頓。 吞吐量的含義是在一段比較長的時間內,沒有用在垃圾收集的時間和總時間的百分比。

減少暫停時間的辦法可以採用小的年輕代和增量收集,但是這以犧牲吞吐率為代價。

Footprint 是一批工作進程的集合,以頁和緩衝行數計量,在物理內存有限或者有很多處理器的系統里,footprint 可代表伸縮性。

Promptness 是對象死去的時間和內存變為可用時的時間差,在分布系統中(包括 RMI)需要考慮。

很大的新生代能提高吞吐率,但是犧牲了 footprint 和 promptness。 Solaris 的 footprint 可以採用 pmap 命令來查看。 [GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs]

上面的三行是 GC 的詳細輸出,我們可以看到兩次小收集和一次大收集。箭頭前後的兩個數字代表 GC 後活的對象的組合長度。括號內的數字代表合計的空間,等於堆大小減去一片生存空間。

除非你遇到暫停的問題,否則,可以分配足夠的內存給 JVM,缺省的 64MB 總是太小。

設置 -Xms 和 -Xmx 為同樣的值能提高 JVM 的預測,但是如果你的選擇不對的話, JVM 不會補償。

當增加處理器時,記得增加內存,因為分配可以並行進行,而 GC 不是並行的。 NewSize 和 MaxNewSize 綁定新生代的長度的低端和高端,設置為一樣大小時和 -Xms 和 -Xmx 一樣解決新生代的預測時間。

如果生存空間太小,拷貝直接進入舊生代,如果太大的話,會空閑在那裡。

除非你碰到過渡的大收集或者暫停時間,否則分配足夠的內存給新生代,缺省的 MaxNewSize (32MB) 往往太小。

如果需要的話,最大的永久代大小可以使用 MaxPermSize 增加。 直接的 GC 調用可以採用 -XX:+DisableExplicitGC 來關閉。

對於大服務器 而言,1.4 的 JVM 能提供 64 bit 尋址能力,提供更大的新生代大小,並發收集來減少大收集引起的暫停的影響。

Java HotSpot Client VM 主要用於減少應用啟動時間以及內存的 footprint 。

Java HotSpot Server VM 和 Java HotSpot Client VM 類似,但是在最大性能上作了

調整。用於長期運行的服務應用。

Solaris 和 Linux 的 J2SE 1.3 隨帶 Java HotSpot Server VM 預安裝。

以下文章點擊率最高

Loading…

     

如果這文章對你有幫助,請掃左上角微信支付-支付寶,給於打賞,以助博客運營