Java 如果新技术失败了怎么办? C++和C语言中,当新的内存分配不正确时,它会引发异常。p>

Java 如果新技术失败了怎么办? C++和C语言中,当新的内存分配不正确时,它会引发异常。p>,java,memory-management,Java,Memory Management,我在Java中找不到有关new行为的任何信息。 那么,如果new在Java中失败(内存不足),会发生什么呢 假设您明确表示内存分配失败,那么它应该抛出 当Java虚拟机由于内存不足而无法分配对象,并且垃圾收集器无法提供更多内存时引发 与Error的所有子类一样,它通常是一种不可恢复的情况,即使从技术上讲您可以捕捉到它: 错误是Throwable的一个子类,它表示一个合理的应用程序不应该试图捕获的严重问题。大多数此类错误都是异常情况。ThreadDeath错误虽然是“正常”情况,但也是错误的一个子

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

假设您明确表示内存分配失败,那么它应该抛出

当Java虚拟机由于内存不足而无法分配对象,并且垃圾收集器无法提供更多内存时引发

Error
的所有子类一样,它通常是一种不可恢复的情况,即使从技术上讲您可以捕捉到它:

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

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


如果您确实没有足够的内存,则抛出OutOfMemoryError。
此外,任何异常都可能由构造函数本身引发。

您可以捕获OutOfMemoryExceptions,但不建议这样做。但是,除非是编码/设计问题,否则垃圾收集器应该负责管理堆

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


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

实际上,JVM实际抛出异常可能需要相当长的时间。当面临内存问题时,JVM将首先尝试尽可能多地丢弃内存。根据JVM配置(GC参数和最大堆内存),当Xmx设置为几GB时,GC周期可能需要几秒钟到几分钟。更糟糕的是,根据所需的内存,JVM可以在抛出异常之前执行几个GC周期

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

如果您担心内存问题,我的建议是,当内存问题出现时,您应该注册并杀死您的程序,因为停止您的程序肯定比让它在未定义的状态下工作要好,因为没有人知道

您可以阅读亨氏歌舞伎关于该主题的以下文章:

再详细介绍一下

/*许可证-LGPL
从OutOfMemory错误中恢复
JavaDocs用于错误状态,在第一句中。。
“错误是Throwable的一个子类,表示
严重的问题,应合理应用
不要试图抓住。”
这个建议导致了一个谬误,即OutOfMemoryError
不应该被抓住和处理。但是这个演示。显示
很容易恢复到提供
向用户提供有意义的信息,以及如何
继续
我的目标是使我的申请“不合理”。-)
*/
导入java.awt.event.ActionListener;
导入java.awt.event.ActionEvent;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入javax.swing.JPanel;
导入javax.swing.JLabel;
导入javax.swing.JProgressBar;
导入javax.swing.JOptionPane;
导入javax.swing.JDialog;
导入javax.swing.Timer;
导入javax.swing.border.EmptyBorder;
导入java.util.ArrayList;
/**演示。显示从OutOfMemory错误中恢复。
一旦遇到OOME,我们的选项相对较少
很少,但我们仍然可以警告最终用户并提供
关于如何纠正问题的建议。
@作家安德鲁·汤普森*/
公共类MemoryRecoveryTest{
公共静态void main(字符串[]args){
//保留内存缓冲区
字节[]缓冲区=新字节[2^10];
ArrayList=新建ArrayList();
最终JProgressBar内存=新JProgressBar(
0,
(int)Runtime.getRuntime().totalMemory());
ActionListener=新建ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
memory.setValue(
(int)Runtime.getRuntime().freemory());
}
};
定时器=新定时器(500,侦听器);
timer.start();
JDialog dialog=新建JDialog();
setTitle(“可用内存”);
JPanel memoryPanel=新的JPanel();
memoryPanel.add(内存);
memoryPanel.setBorder(新的空订单(25,25,25,25));
添加(memoryPanel);
dialog.pack();
对话框.setLocationRelativeTo(空);
对话框.setVisible(true);
addWindowListener(新的WindowAdapter(){
@凌驾
公共作废窗口关闭(WindowEvent we){
系统出口(0);
}
} );
//提前准备内存警告面板
JPanel memoryWarning=新的JPanel();
memoryWarning.add(新的JLabel(
“内存不足,无法执行”+
“完成任务!
使用变体”+ “指分配更多内存的应用程序。”); 试一试{ //完成“记忆密集型”任务 while(true){ 添加(新对象()); } }捕获(OutOfMemoryError oome){ //为虚拟机提供一些内存
// 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();
/*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);
        }
    }
}