2013-06-22 81 views
5

我在LogCat中收到 OutOfMemoryError消息,我的應用程序崩潰,因爲錯誤未被捕獲。

引起 OutOfMemoryError的兩件事
1.將大文本文件讀入字符串。
2.將該字符串發送到我的TextView。

簡單地在這兩件事情上添加一個catch不僅捕獲 OutOfMemoryError,但似乎完全解決了內存不足的問題。
沒有更多的崩潰和LogCat中沒有更多的錯誤消息。該應用程序運行完美。

這怎麼可能?究竟發生了什麼?


'捕捉'OutOfMemoryError完全解決了內存不足的問題?

有了這個代碼,我得到的錯誤信息&應用程序崩潰:

try 
{ 
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next(); 
} 
catch (FileNotFoundException e) 
{ 
e.printStackTrace(); 
} 


myTextView.setText(myString); 



僅僅通過 '追趕' 的的OutOfMemoryError,在logcat中沒有更多的錯誤消息,並沒有崩潰:

try 
{ 
myString = new Scanner(new File(myFilePath)).useDelimiter("\\A").next(); 
} 
catch (FileNotFoundException e) 
{ 
e.printStackTrace(); 
} 
catch(OutOfMemoryError e) 
{ 
} 


try 
{ 
myTextView.setText(myString); 
} 
catch(OutOfMemoryError e) 
{ 
} 
+2

以查看日誌在OutOfMemoryError catch塊中添加e.printstacktrace – Calvin

+1

同意@Droider。您沒有看到錯誤消息,因爲您沒有像以前那樣打印它們。 – csmckelvey

+0

請參閱http://stackoverflow.com/questions/2679330/catching-java-lang-outofmemoryerror – Raedwald

回答

1

如果你趕上的OutOfMemoryError,垃圾收集器試圖釋放先前使用的內存中,因此應用程序可以進行,如果應用程序將讓垃圾收集器做它的工作(即該應用程序不再引用您的大字符串)。

然而,捉一個OutOfMemoryError是遠離防呆。見Catching java.lang.OutOfMemoryError?

2

我猜你的字符串是不完全加載,或者即使它是(很可能只是添加文本後拋出錯誤),會發生什麼取決於可用於您的應用程序,以便趕上OutOfMemoryError當前內存是不是一個這裏可行的解決方案。

如果你真的想加載一個大的字符串文件並將它顯示在EditText中,我建議你只加載一小部分文件(比如說50kB),並實現某種類型的分頁,加載下一個50kB。您也可以在用戶滾動瀏覽EditText時加載額外的行。

1

當您發現異常時,JVM嘗試通過調用垃圾收集器並刪除不再使用的對象來嘗試從中恢復。

這可能會解決你的情況的問題。但可想而知,由於出現壞的編碼和內存泄漏在你的代碼的問題。捕捉不會解決問題,因爲GC不會收集任何對象。 GC會更頻繁地踢,你的應用程序的性能就會下降,直到它變得不可用。

基本上,當JVM不能堆新對象分配更多的內存此錯誤發生的情況。捕獲異常並讓GC清理並釋放內存可能是一種解決方案,但您絕對不能確定您處於可恢復狀態。我會使用catch塊從錯誤中恢復,記錄並關閉應用程序。如果你想在這種情況下解決內存問題,請正確執行並使用更多內存初始化JVM(使用java參數-Xmx

+0

我在圖像反射方法中遇到異常。如果發生錯誤,我是否可以捕獲錯誤,停止處理,清理對象並簡單地使用原始圖像? – frostymarvelous

+0

捕獲這樣的異常真的被認爲是不好的做法。更好的做法是通過1)試圖找到代碼泄漏的位置,2)在程序啓動時增加給JVM的內存(使用-Xmx)以避免發生該異常。另外,我不確定「圖像反射法」是什麼意思,你能解釋一下嗎? – darijan

+0

基本上,我從反映圖像的現有圖像創建新圖像。對不起,我想那是反射。 無論如何,代碼不會泄漏。有時在使用Bitmap.createBitmap創建新圖像時出現錯誤。如果全部失敗,我將不得不使用二次抽樣,但我認爲這些圖像已經足夠小了。 – frostymarvelous