java 설정 새로운 것이 실패한다면?




jvm memory structure (4)

C ++과 C #에서는 새로운 메모리를 할당 할 수 없을 때 예외가 발생합니다.

Java에서의 새로운 동작에 대한 정보를 찾을 수 없었습니다. 새로운 메모리가 Java (메모리 부족)에서 실패하면 어떻게 될까요?


실제로 충분한 메모리가 없으면 OutOfMemoryError가 발생합니다. 또한 예외는 생성자 자체에 의해 발생 될 수 있습니다.


OutOfMemoryError 좀 더.

/*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);
        }
    }
}

자바가 객체를 할당하기에 충분한 메모리를 얻을 수 없을 때 OutOfMemoryError 얻습니다.

실제로 JVM이 실제로 예외를 던질 때까지 예외가 발생할 수 있습니다. 메모리 문제가 발생하면 JVM은 가능한 한 많은 메모리를 낭비하지 않습니다. JVM 구성 (GC 매개 변수 및 최대 힙 메모리)에 따라 GC 사이클은 Xmx가 수 기가 바이트로 설정된 상태에서 수 초에서 수 분이 소요될 수 있습니다. 더 나쁜 것은 필요한 메모리에 따라 JVM이 예외를 throw하기 전에 여러 GC 사이클을 수행 할 수 있다는 것입니다.

예외가 throw되면 (자), 캐치되어 있지 않은 예외로서 처리됩니다. 따라서 예외가 발생한 스레드의 호출 스택 맨 위로 전파됩니다. 예외가 캐치되지 않기 때문에 스레드는 죽기 전에 System.err 스택 트레이스를 표시합니다. 그게 다야. 모노 스레드 프로그램에서는 프로그램이 종료됩니다. 다중 스레드 프로그램에서이 스레드가 종료되면 프로그램이 불안정한 구성으로 계속 실행될 수있는 충분한 메모리가 확보 될 수 있습니다.

메모리 문제가 우려된다면, 메모리 문제가 발생할 때 UncaughtExceptionHandler 를 등록하여 UncaughtExceptionHandler 를 등록시켜야합니다. 아무도 알지 못하는 상태에서 정의되지 않은 상태로 작업하는 것보다 프로그램을 중지하는 것이 좋습니다.

주제에 대한 하인즈 카 부츠 (Heinz Kabutz)의 다음 기사를 읽을 수 있습니다.


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






memory-management