天天看點

JAVA應用Crash錯誤分析

昨天晚上啟動jboss之後,發現點選某個頁面,總是crash掉;控制台資訊如下:

----------------------------------------------------------------------------------------------------------------

#

# A fatal error has been detected by the Java Runtime Environment:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6dd1a7a1, pid=6044, tid=2744

#

# JRE version: 6.0_22-b04

# Java VM: Java HotSpot(TM) Server VM (17.1-b03 mixed mode windows-x86 )

# Problematic frame:

# V [jvm.dll+0x1aa7a1]

#

# If you would like to submit a bug report, please visit:

# http://java.sun.com/webapps/bugreport/crash.jsp

#

----------------------------------------------------------------------------------------------------------------

後來同僚将他的JOBSS給我,當時是OK了,同僚說是JVM啟動參數不一樣,當時也沒有深究;結果今天早上上來在什麼都沒有修改的情況下,居然又crash了;乘着這個加深學習了下JVM的一些參數配置知識。

[b](一)産生錯誤的原因[/b]

造成嚴重錯誤的原因有多種可能性。Java虛拟機自身的Bug是原因之一,但是這種可能性很小。在絕大多數情況下,是由于系統的庫檔案、API或第三方的庫檔案造成的;或者是系統資源的短缺也有可能造成這種嚴重的錯誤。

[b](二).對日志檔案的分析[/b]

日志頭中“EXCEPTION_ACCESS_VIOLATION ”标明了日志錯誤類型。一般還有另外一種常見的錯誤類型:EXCEPTION_STACK_OVERFLOW;

日志中另外一個有用的資訊就是:

[color=red]# Problematic frame:

# V [jvm.dll+0x1aa7a1][/color]

它說明Crash的時候,JVM正在從哪個庫檔案執行代碼。除了“V”以外,還有可能是“C”、“j”、“v”、“J”。具體的表示意思如下:

FrameType Description:

C: Native C frame

j: Interpreted Java frame

V: VMframe

v: VMgenerated stub frame

J: Other frame types, including compiled Java frames

EXCEPTION_ACCESS_VIOLATION加上“ # Problematic frame: # V [jvm.dll+....”說明一般是記憶體回收引起的問題。對于記憶體回收的錯誤,一般采取改變回收的算法和參數的方法來繞過去。可改變記憶體回收的算法,或者優化JVM配置參數來解決。

是以在本次錯誤中,優化JBOSS中JVM的啟動參數可以解決問題。但是為什麼一模一樣的配置,昨天晚上OK的,今天早上卻失敗了?具體的我現在也沒有明确的答案,我猜測可能是在特定的條件下(比如說本機的系統資源,遠端調用的系統穩定性,以及網絡是否繁忙等都可能會産生影響)産生的。

[b](三).其他常見錯誤[/b]

[color=red]1.java.lang.OutOfMemoryError: Java heap space[/color]

當設定JBOSS啟動參數:

set JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx128m

背景日志報錯:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxAO' defined in resource loader resource [/xxx/biz/bean/biz-xx.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxxServices' defined in resource loader resource [/xxx/biz/bean/biz-xxx.xml]: Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: Java heap space
           

分析:

這裡是指最大堆記憶體設定太小,可以通過設定JBOSS啟動參數:–Xmx 增加堆記憶體即可;

[color=red]2.java.lang.OutOfMemoryError: GC overhead limit exceeded[/color]

當設定JBOSS啟動參數:

set JAVA_OPTS=%JAVA_OPTS% -Xms128m –Xmx256m

日志錯誤:

java.lang.OutOfMemoryError: GC overhead limit exceeded
           

分析:

意味着太多的時間花在了垃圾收集上面,SUN的建議是指定垃圾回收的算法,加上啟動參數-XX:-UseGCOverheadLimit,進而限制JVM在抛出OutOfMemoryError之前限制其耗費在GC上的時間。

SUN的原文:

The parallel / concurrent collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

[color=red]3.另外一種常見錯誤:ava.lang.OutOfMemoryError: PermGen space [/color]

這一部分用于存放Class和Meta的資訊,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程式運作期對PermGen space進行清理,是以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。

解決方法: 手動設定MaxPermSize大小

另外:

JBOSS啟動參數說明

另外:

JBOSS啟動參數說明

-Xms256m 初始的java記憶體堆大小 256M

-Xmx2048m 最大的java記憶體堆大小 2048M

-XX:PermSize=128m GC預留的記憶體,如果你的應用有大量的Class被動态載入或解除安裝,你應該不這個參數設大些

-XX:MaxPermSize=256m 最大的GC預留記憶體

-Dsun.rmi.dgc.client.gcInterval=3600000 RMI用戶端GC發生周期的設定

-Dsun.rmi.dgc.server.gcInterval=3600000 RMI服務端GC發生周期的設定

參考資料:

[url]http://blog.csdn.net/sfdev/archive/2008/01/24/2063928.aspx[/url]

[url]http://developers.sun.com.cn/blog/yutoujava/entry/20070411#comments[/url]