2013-07-11 46 views
3

我正在設計一個解決方案,其中包括一個C++庫和一些使用該庫通過JNI的Java應用程序。我應該從應用程序本機庫(通過JNI使用)拋出java.lang.OutOfMemoryError嗎?

C++庫大量分配本機內存。當分配失敗時,可以從C++代碼中檢測出來。如果未能分配,應該拋出一些可拋出的東西來向Java代碼報告。

的2個選擇被認爲是:

  1. 擲java.lang.OutOfMemoryError從我的C++代碼
  2. 添加mylibrary.MyLibraryOutOfMemoryError(擴展java.lang.RuntimeException或java.lang.Error的),和拋它

什麼是正確的選擇,爲什麼?

+0

你必須**永遠不會拋出一個OOM錯誤,讓應用程序拋出它。此外,你**不能**處理錯誤,他們的目的是終止應用程序。 –

+0

感謝您的回覆!您能否澄清一下(a)爲什麼OOM不應該從我的JNI代碼中拋出?例如在這裏他們甚至提供了一個方便的方法來拋出具體的OOM:http://stackoverflow.com/questions/230689/best-way-to-throw-exceptions-in-jni-code(b)你是什麼意思,讓你的應用程序丟它? – user2573701

+0

從你所說的話來看,這樣的錯誤是不可恢復的;那麼你可能應該使用'RuntimeException'。本地代碼的分配失敗並不妨礙JVM的正常工作,但會阻止應用程序正常運行。如果JVM本身未能分配,反正你會很快看到一個'Error'。 – fge

回答

5

OutOfMemoryError有特定的含義:

當Java虛擬機無法分配一個對象時拋出,因爲它超出了內存,並且可以通過垃圾收集器提供沒有更多的內存

由於本地堆分配失敗,因此您的代碼不適合引發此錯誤。儘管ByteBuffer.allocateDirect()做什麼。

我會建議您創建自己的例外,擴展Error。它應該是而不是是一個檢查異常,因爲正在運行的程序可以做很少/沒有任何事情可以避免該錯誤。

+0

它應該擴展'Error'而不是'RuntimeException'。否則,它會被捕獲處理程序捕獲以用於「異常」,這通常不是您在內存不足時想要的。 ('OutOfMemoryError'也是'Error'而不是'RuntimeException') –

+0

@ main-- - 這是一個有效的點;我編輯了我的回覆。然而,請注意,許多「最後一關」catch塊(包括'Thread'的未捕獲的異常處理程序)實際上捕獲了'Throwable'而不是'Exception'。 – parsifal

+0

謝謝! 「...當Java虛擬機由於內存不足而無法分配對象時拋出,並且垃圾收集器不再提供內存......」<=它看起來像鍵是JVM從Java代碼角度來看:對我來說它可能是(a)JVM,(b)JVM +所有加載的本地庫(包括我的)。 – user2573701

相關問題