如果新的失败怎么办?

在C ++和C#中,当新的无法分配内存时,它会抛出exception。

我在Java中找不到有关new的行为的任何信息。 那么如果新的Java失败(内存不足)会发生什么?

假设您特意表示内存分配失败,那么它应该抛出OutOfMemoryError

当Java虚拟机由于内存不足而无法分配对象时抛出,垃圾收集器不再提供更多内存。

Error所有子类一样,它通常是一个不可恢复的条件,即使从技术上讲你可以捕获它:

Error是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。 大多数此类错误都是exception情况。 ThreadDeath错误,虽然是“正常”条件,但也是Error的子类,因为大多数应用程序不应该尝试捕获它。

一个方法不需要在其throws子句中声明在执行方法期间可能抛出但未捕获的任何Error类,因为这些错误是永远不应发生的exception情况。

当Java无法获得足够的内存来分配对象时,您将获得OutOfMemoryError 。

实际上,JVM实际抛出exception可能需要很长时间。 当遇到内存问题时,JVM将首先尝试尽可能多地浪费内存。 根据JVM配置(GC参数和最大堆内存),GC周期可能需要几秒到几分钟,而Xmx设置为几千兆字节。 更糟糕的是,根据所需的内存,JVM可以在抛出exception之前执行几个GC周期。

抛出exception时,它将被处理为任何未捕获的exception。 因此,它将传播到引发exception的线程的调用堆栈的顶部。 由于exception未被捕获,该线程将在死亡之前在System.err上显示堆栈System.err 。 就这样。 在单线程程序中,这将导致程序退出。 在multithreading程序中,此线程死亡可以释放足够的内存,以使程序在不稳定的配置中继续运行。

如果你担心内存问题我的建议是你应该注册和UncaughtExceptionHandler来解决你的程序出现内存问题,因为停止你的程序肯定比在没有人知道的情况下让它工作在一个未定义的状态更好。

您可以阅读Heinz Kabutz关于此主题的以下文章:

  • 在JDK 1.5中捕获未捕获的exception
  • OutOfMemoryError警告系统

如果你真的没有足够的内存,则抛出OutOfMemoryError。 构造函数本身也可能抛出任何exception。

关于OOME的更多信息 。

 /*License - LGPL 

Recovery from an OutOfMemory Error

The JavaDocs for Error state, in the first sentence..

"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

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.

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 list = new ArrayList(); 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( "There is not enough memory to" + " complete the task!
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); } } }

您可以捕获OutOfMemoryExceptions但不推荐。 但是,除非它是编码/设计问题 – 垃圾收集器应该负责管理堆。

如果您认为您将进行大量数据处理并且可能会运行内存,那么您可以在开始执行之前始终检查可用空间(从此链接复制代码段)。

 // 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();