2010-02-03 206 views
8

我寫了一個需要處理數千個文本文件的Java程序(全部需要在內存中加載)。它可以和多達123個輸入文件一起工作,但是當我運行它來處理大約5000個文件時,它會在路中間意外終止,而不會給出任何錯誤消息/異常。任何人都可以告訴我可能出錯的線索嗎?Java程序意外終止,沒有任何錯誤信息

我在Mac OS Leopard上使用jdk1.6,內存爲2GB。

+0

如何大是這些文件(在內存佔用)?你有沒有使用任何工具觀察自由記憶? – lexu 2010-02-03 05:56:22

+0

你如何確定沒有生成錯誤消息或異常? – 2010-02-03 07:07:32

+0

嘗試編寫一些日誌並找出程序每次終止的位置,這可以給出關於哪行代碼有問題的任何線索 – 2010-02-03 07:15:32

回答

4

鑑於這是你的計劃,我建議你做到以下幾點:

首先,改變main方法,使一切都在報告所有捕獲的異常使用try/catch塊完成的;例如這樣的事情:

public static void main(String[] arghhhhh) { 
    try { 
     ... 
    } catch (Throwable ex) { 
     System.err.println("Uncaught exception - " + ex.getMessage()); 
     ex.printStackTrace(System.err); 
    } 
} 

其次,尋找你可能「擠壓」意外的異常,抓住他們,而不報告他們。

三,尋找任何你可能會默默地打電話給System.exit()的地方。這也可能發生在圖書館......如果你使用的是寫得不好的書。

如果這些措施不給你答案,揣摩如何申請是由

  • 退出從調試器中運行設置關鍵點斷點,或
  • 通過添加微量打印語句在關鍵點。
+0

謝謝,我會嘗試這些.. – Fahim 2010-02-03 06:37:34

+0

是的,我有OutOfMemory錯誤,這是來自一個遞歸函數,順序遍歷一個136600節點的樹。這是由於遞歸?我應該嘗試通過循環去除遞歸嗎?那可能嗎? – Fahim 2010-02-03 16:41:57

+0

我懷疑遞歸(文件的目錄樹)是造成這種情況。您需要使用內存分析器來查找內存的使用情況。 – 2010-02-03 21:34:56

2

你是否同時打開文件?如果您一次加載太多文件,則可能內存不足。如果文件足夠大,則可能只會打開一個文件而導致內存不足。另外,確保在完成文件時關閉文件。

+0

大多數文件大小爲4 KB,最大的文件大小爲193 KB。所有文件的大小總計高達20 MB。我正在一個接一個地閱讀這些文件。 我看到那些被成功讀取。這些文件實際上爲我的程序提供了輸入。我不會對這些文件進行任何更改。我的程序在處理輸入的過程中中止。 如果堆耗盡,我會期待內存異常。因爲,我沒有收到任何錯誤消息,所以我沒有任何線索。 – Fahim 2010-02-03 06:30:17

+0

*我關閉了所有文件。我還沒有用任何工具觀察空閒內存?你能提出任何工具嗎? – Fahim 2010-02-03 06:34:26

1

檢查是否有任何try/catch塊沒有正確記錄異常。

它很可能是OutofmemoryError。確保控制檯未被重定向。

+0

控制檯未重定向。 – Fahim 2010-02-03 06:35:29

3

看來你正在得到OutofmemoryError

如果是這種情況,請嘗試增加堆內存大小。

java -Xms<initial heap size> -Xmx<maximum heap size> 
+1

是的,我有OutOfMemory錯誤,它來自一個遞歸函數,它按順序遍歷136600個節點的樹。這是由於遞歸?我應該嘗試通過循環去除遞歸嗎?那可能嗎? 是的,我可以增加堆大小,我認爲這是最後的選擇。 – Fahim 2010-02-03 16:43:59

+0

我該如何檢查當前的堆大小?每次運行我的程序之前,我是否必須增加堆大小? – Fahim 2010-02-04 03:47:37

+0

您可以使用JDK附帶的JConsole實用程序。 – 2010-02-04 12:36:47

0

主要有兩個原因。

  1. 發生「未處理」的系統故障,即java.lang.OutOfMemoryError。
  2. 發生了「未處理」的應用程序故障。
  3. System.exit已被調用。

爲了應對這些情況考慮做以下步驟:

  • 查找在你通話對System.exit代碼。
  • 確保您處理啓動Java堆棧幀中的所有異常,即主法:

    嘗試{ ..code }趕上(的Throwable t)的{ t.printStackTrace }

  • 確保您有在輸出和錯誤指向控制。您可以通過編程方式將它們設置爲具體文件:

System.setOut(new PrintStream(「output.txt」)); System.setErr(new PrintStream(「err.txt」));

  • 開始ARGS爲:-Xloggc:gc.log -XX:+ PrintGCDetails -XX:+ PrintGCTimeStamps