回答
假設你專門意味着內存分配失敗,那麼它應該拋出時,Java虛擬機無法分配一個對象,因爲它是內存不足OutOfMemoryError
拋出,並沒有更多的內存可由垃圾收集器提供。
喜歡Error
所有子類,它通常是不可恢復的情況,即使在技術上你可以抓住它:
一個錯誤是Throwable的子類,表示嚴重的問題,一個合理的應用程序不應該試圖捕捉。大多數此類錯誤都是異常情況。 ThreadDeath錯誤雖然是一個「正常」條件,但也是Error的一個子類,因爲大多數應用程序不應該試圖捕獲它。
一個方法不需要在其throws子句中聲明在執行該方法期間可能拋出的錯誤的任何子類,但未捕獲,因爲這些錯誤是永遠不會發生的異常情況。
如果你真的沒有足夠的內存OutOfMemoryError被拋出。 也可以由構造函數本身拋出任何異常。
你可以捕獲OutOfMemoryExceptions但不推薦。但是,除非是編碼/設計問題 - 垃圾收集器應負責管理堆。
如果您認爲您將進行大量數據處理並可能運行內存,那麼您可以在開始執行之前始終檢查可用空間(從此link複製代碼段)。
// Get current size of heap in bytes
long heapSize = Runtime.getRuntime().totalMemory();
// Get maximum size of heap in bytes. The heap cannot grow beyond this size.
// Any attempt will result in an OutOfMemoryException.
long heapMaxSize = Runtime.getRuntime().maxMemory();
// Get amount of free memory within the heap in bytes. This size will increase
// after garbage collection and decrease as new objects are created.
long heapFreeSize = Runtime.getRuntime().freeMemory();
OOM不僅是由於編碼/設計問題,至少不是你可以隨時控制的。在著名的第三方的API,Java的生活(和誰肯定會繼續),在此期間,已經非常普遍,內存泄漏想到......第三方的API – SyntaxT3rr0r 2011-01-24 18:24:37
當然選擇是在我看來,設計的一部分。 – CoolBeans 2011-01-24 19:01:20
Java的時候無法獲得足夠的內存來分配一個對象,你會得到一個OutOfMemoryError。
實際上,異常可能需要很長時間才能被JVM實際拋出。當面對內存問題時,JVM將首先嚐試儘可能多地存儲內存。根據JVM配置(GC參數和最大堆內存),當Xmx設置爲幾個千兆字節時,GC週期可能需要幾秒到幾分鐘的時間。更糟的是,根據所需的內存,JVM可以在拋出異常之前執行幾個GC週期。
當異常拋出時,它將作爲任何未捕獲的異常進行處理。因此它會傳播到引發異常的線程的調用堆棧的頂部。由於異常未被捕獲,線程將在死亡之前在System.err
上顯示堆棧跟蹤。就這樣。在單線程程序中,這會導致程序退出。在多線程程序中,此線程死亡可釋放足夠的內存,以便程序繼續以不穩定的配置運行。
我的建議,如果你擔心內存問題,你應該註冊並且UncaughtExceptionHandler當內存問題出現時殺死你的程序,因爲停止你的程序肯定比讓它在沒有任何人知道的未定義狀態下工作更好。
您可以在主題閱讀亨氏Kabutz下面的文章:
多了幾分OOME。
/*License - LGPL
<h3>Recovery from an OutOfMemory Error</h3>
<p>The JavaDocs for Error state, in the first sentence..
<blockquote>"An Error is a subclass of Throwable that indicates
serious problems that a reasonable application should
not try to catch."</blockquote>
<p>This advice has led to the fallacy that an OutOfMemoryError
should not be caught and dealt with. But this demo. shows
that it is quite easy to recover to the point of providing
the user with meaningful information, and advice on how to
proceed.
<p>I aim to make my applications 'unreasonable'. ;-)
*/
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JOptionPane;
import javax.swing.JDialog;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import java.util.ArrayList;
/** A demo. showing recovery from an OutOfMemoryError.
Our options once an OOME is encountered are relatively
few, but we can still warn the end user and provide
advice on how to correct the problem.
@author Andrew Thompson */
public class MemoryRecoveryTest {
public static void main(String[] args) {
// reserve a buffer of memory
byte[] buffer = new byte[2^10];
ArrayList<Object> list = new ArrayList<Object>();
final JProgressBar memory = new JProgressBar(
0,
(int)Runtime.getRuntime().totalMemory());
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
memory.setValue(
(int)Runtime.getRuntime().freeMemory());
}
};
Timer timer = new Timer(500, listener);
timer.start();
JDialog dialog = new JDialog();
dialog.setTitle("Available Memory");
JPanel memoryPanel = new JPanel();
memoryPanel.add(memory);
memoryPanel.setBorder(new EmptyBorder(25,25,25,25));
dialog.add(memoryPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
dialog.addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// prepare a memory warning panel in advance
JPanel memoryWarning = new JPanel();
memoryWarning.add(new JLabel(
"<HTML><BODY>There is not enough memory to" +
" complete the task!<BR> Use a variant " +
" of the application that assigns more memory."));
try {
// do our 'memory intensive' task
while(true) {
list.add(new Object());
}
} catch(OutOfMemoryError oome) {
// provide the VM with some memory 'breathing space'
// by clearing the buffer
buffer = null;
// tell the user what went wrong, and how to fix it
JOptionPane.showMessageDialog(
dialog,
memoryWarning,
"Out of Memory!",
JOptionPane.ERROR_MESSAGE);
}
}
}
- 1. MPMoviePlayerViewController,如果失敗會怎麼樣?
- 2. Java ExecutorService - 如果awaitTermination()失敗會怎麼樣?
- 3. 如果觸發器失敗會怎麼樣?
- 4. 如果CancelIo失敗怎麼辦?
- 5. 如果google.load失敗,該怎麼辦?
- 6. 如果mysql_query()失敗,該怎麼辦?
- 7. _vti_bin Lists.asmx;如果第一次登錄Web服務失敗會怎麼樣?
- 8. 如果Django的中繼單元測試失敗會怎麼辦?
- 9. 如果你刪除.gitignore會怎麼樣?
- 10. 錯誤處理php_network_getaddresses:getaddrinfo失敗。怎麼樣?
- 11. 如果@PostConstruct失敗,Bean會被創建
- 12. Git:如果我在推送前忘記更新會怎麼樣
- 13. 如果失敗的測試會使連續構建失敗?
- 14. CruiseControl和MSTest:如果測試失敗,那麼構建失敗
- 15. 如果在觸發器中失敗,則在TABLE_A中插入不應失敗。怎麼樣?
- 16. 如果html_escape會停止轉義'&'會怎麼樣?
- 17. 如果SPARQL查詢的結果是資源會怎麼樣?
- 18. JTA XAResource多個數據庫:如果在準備後兩階段提交失敗會怎麼樣
- 19. Hibernate EntityListeners - 在persist調用之前修改模型的PrePersist方法 - 如果持續調用失敗會怎麼樣?
- 20. 這怎麼可能?紅寶石如果循環失敗
- 21. 如果「git push heroku master」失敗,該怎麼辦?
- 22. 期待列表[未來],如果未來失敗,該怎麼辦?
- 23. 如果「記錄過程」失敗,我該怎麼辦?
- 24. 如果git-am失敗,「索引中不存在」怎麼辦?
- 25. 如果git-am與「不匹配索引」失敗,該怎麼辦?
- 26. 如果雙散列函數也失敗,我應該怎麼做
- 27. C#EntityFramework Up方法¿如果sql在中間失敗怎麼辦?
- 28. 如果鈦靜默API調用失敗怎麼辦?
- 29. 如果重新定義內聯函數會怎樣?
- 30. AWS Lambda和DynamoDB流。如果執行失敗會怎樣?下次嘗試是否會處理相同的記錄?
如果您有足夠的理由去解決已知問題,那麼可以編寫從此條件恢復的代碼。這很少是一個好主意,減少內存消耗或增加最大內存通常是最佳選擇。 – 2011-01-24 20:52:30