Какая разница между StackOverflowError и OutOfMemoryError

Какая разница между StackOverflowError и OutOfMemoryError и как их избежать в приложении?

Ответ 1

Короткий ответ:

  • OutOfMemoryError связан с кучей.
  • StackOverflowError связан со стеком

Длинный ответ:

Когда вы запускаете JVM вы определяете, сколько ОЗУ он может использовать для обработки. JVM делит это на определенные области памяти для целей обработки, два из них - Stack & Heap

Если у вас есть большие объекты (или) ссылочные объекты в памяти, то вы увидите OutofMemoryError. Если у вас есть сильные ссылки на объекты, то GC не может очистить пространство памяти, выделенное для этого объекта. Когда JVM пытается выделить память для нового объекта и недостаточно свободного места, он выбрасывает OutofMemoryError потому что он не может выделить необходимый объем памяти.

Как избежать: убедитесь, что ненужные объекты доступны для GC

Все ваши локальные переменные и вызовы методов, относящиеся к данным, будут в стеке. Для каждого вызова метода будет создан один кадр стека, и локальные данные, а также данные, связанные с вызовом метода, будут помещены в кадр стека. Как только выполнение метода будет завершено, кадр стека будет удален. ONE WAY воспроизвести это, есть бесконечный цикл для вызова метода, вы увидите stackoverflow ошибки, потому что кадр стека будет заполнен методом данными для каждого вызова, но он не будет освобожден (удален).

Как избежать: убедитесь, что вызовы методов заканчиваются (не в бесконечном цикле)

Ответ 2

Представьте, что у вас есть функция, подобная следующей

public void f(int x) {
    return f(x + 1);
}

Когда вы вызовете это, вызов вызовет f снова и снова и снова. При каждом вызове в стек хранится бит информации. Поскольку размер стека ограничен, вы получите StackOverflowError.

Теперь представьте следующий код:

for (int i = 1; i > 0; i++)
    vector.add(new BigObject());

где BigObject - обычный объект Java. Как вы видите, цикл никогда не заканчивается. Каждое выделение выполняется в куче, поэтому оно будет заполнено BigObject, и вы получите OutOfMemoryError.

Повторить:

  • OutOfMemoryError вызывается при создании объектов
  • StackOverflowError вызывается при вызове функций

Ответ 3

StackOverflowError происходит, когда вы выполняете слишком много методов один внутри другого (например, с бесконечной рекурсией), который ограничен размером стека.

OutOfMemoryError происходит, когда JVM исчерпывает пространство для выделения новых объектов, которые выделяются в куче.

Ответ 4

В виртуальной машине Java существует несколько областей памяти:

  • Стек виртуальной машины Java
  • Область кучи
  • Область методов
  • Пул постоянной времени выполнения
  • Нативные стеки методов

Во всех вышеизложенных случаях вы можете выбрать свою точность, чтобы память, выделенная для этой области памяти, была исправлена ​​или будет динамически изменена во время выполнения.

Теперь о вопросе OutOfMemoryError применим для всех перечисленных выше. OutOfMemoryError будет выбрасываться, если будет произведено расширение памяти любой из области памяти, но достаточное количество памяти недоступно для размещения.

и StackOverFlowError применимо для стека Native Method Stack и Java Virtual Machine Stack. StackOverFlowError будет выбрано Если вычисление в потоке требует большего стека, чем разрешено.

Для подробной справки вы можете прочитать СТРУКТУРА ВИРТУАЛЬНОЙ МАШИНЫ JAVA

Ответ 5

В памяти есть две (2) области кучи и стека.

  • стек памяти используется для хранения локальных переменных и вызова функции.
  • память кучи используется для хранения объектов в Java

Если в стеке нет памяти для хранения вызова функции или локальной переменной, JVM будет бросать java.lang.StackOverFlowError,

while, если больше нет кучи пространства для создания объекта, JVM будет бросать java.lang.OutOfMemoryError:

Ответ 6

Следующие исключительные условия связаны со стеками виртуальной машины Java:

Если для вычисления в потоке требуется большая виртуальная машина Java стек, чем разрешено, виртуальная машина Java бросает StackOverflowError.

Если стеки виртуальной машины Java могут быть динамически расширены и попытка расширения, но недостаточная память может быть доступна для осуществления расширения или если недостаточно памяти доступный для создания исходного стека виртуальной машины Java для нового thread, виртуальная машина Java генерирует OutOfMemoryError.

Следующее исключительное условие связано с кучей:

Если вычисление требует больше кучи, чем может быть доступно автоматическая система управления хранением данных, виртуальная машина Java бросает OutOfMemoryError.

Следующее исключительное условие связано с областью метода:

Если память в области метода не может быть доступна для удовлетворения запрос на размещение, виртуальная машина Java генерирует OutOfMemoryError.

Следующее исключительное условие связано с построением пула констант времени выполнения для класса или интерфейса:

При создании класса или интерфейса, если построение постоянный пул времени выполнения требует больше памяти, чем может быть доступен в области методов виртуальной машины Java, виртуальной машины Java Машина выбрасывает OutOfMemoryError.

Следующие исключительные условия связаны со стеками собственных методов:

Если для вычисления в потоке требуется более крупный собственный стек методов, чем это разрешено, виртуальная машина Java генерирует StackOverflowError.

Если встроенные стеки методов могут быть динамически расширены и собственный метод стека, но недостаточно памяти доступны, или если недостаточно памяти для создания исходный собственный стек методов для нового потока, виртуальный Java Машина выбрасывает OutOfMemoryError.

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html

2.5.2. Стойки виртуальной машины Java

2.5.3. Heap

2.5.4. Область метода

2.5.5. Постоянный пул времени выполнения

2.5.6. Нативные стеки методов

2,6. Рамки

Ответ 7

StackOverflowError: выбрасывается, когда происходит переполнение стека, потому что приложение слишком сильно пересчитывается.

OutOfMemoryError: брошен, когда виртуальная машина Java не может выделить объект, потому что в нем нет памяти, и сборщик мусора может быть недоступен.

Ответ 8

Из Javadocs: Исключительные условия, связанные со стеками JVM:

1), если для создания начального стека JVM для нового потока может быть предоставлена ​​недостаточная память, JVM выдает OutOfMemoryError.

2) Если для вычисления в потоке требуется больший стек JVM, чем разрешено, JVM выдает StackOverflowError.

3) Если стек JVM можно динамически развернуть, а попытка расширения будет предпринята, но недостаточная память может быть доступна для осуществления расширения, JVM выбрасывает OutOfMemoryError.

Исключительные условия, связанные с кучей:

1) Если для вычисления требуется больше кучи, чем может быть доступно системой автоматического управления хранилищем, JVM выдает OutOfMemoryError.

Ответ 9

Для запуска Java-программы требуется память. Эта память выделяется из операционной системы для JVM (виртуальная машина Java) и делится на две части, а именно:

  1. Память стека
  2. Память кучи Память стека Память стека используется, когда мы вызываем метод или запускаем какой-то поток. Поскольку мы продолжаем вызывать методы, текущее состояние программы и локальные переменные помещаются в память стека. После завершения метода его локальные переменные извлекаются из памяти стека.

    открытый класс test {static void innerMethod (int i) {System.out.println(i); } static void outerMethod(String str, int i){ innerMethod(i); } static void externalMethod (String str, int i) {innerMethod (i); System.out.println(str); System.out.println (ул); } }

    public static void main(String[] args){
        outerMethod("Print me !!", 10);
    }
    

    } Здесь соответствующий стек вызовов. SP обозначает указатель стека. Память кучи Память кучи используется, когда мы объявляем и инициализируем объект. Этот объект может быть массивом, переменной, константой и т.д.

StackOverflowError vs OutOfMemoryError: Объем памяти, предоставляемой операционной системой для запуска Java-программы, ограничен, как и объем памяти стека и кучи.

java.lang.stackOverflowError возникает, когда у нас заканчивается память стека. Это может возникнуть, когда мы вызываем рекурсивный метод без надлежащего условия завершения. Если мы продолжаем вызывать методы, информация о состоянии будет добавляться в стек вызовов, в памяти стека не хватит места. Вот пример кода, который выкинет эту ошибку.

public class stackOverflowExample{
    private static void printFunction(int i){
        printFunction(i+1);
        System.out.println(i);
    }
    public static void main(String[] args){
        printFunction(0);
    }
}

Чтобы устранить эту ошибку, можно написать правильное условие завершения. Давайте добавим завершающее условие к предыдущему фрагменту кода:

public class stackOverflowExample{
    private static void printFunction(int i){
        if(i==10)return;    //Terminating Condition
        printFunction(i+1);
        System.out.println(i);
    }
    public static void main(String[] args){
        printFunction(0);
    }
}

java.lang.outOfMemoryError вызывается, когда у нас заканчивается память кучи и память не доступна для новых объектов. Это возникает, когда у нас есть живые ссылки на наш объект или мы пытаемся создать очень большой объект. Если объект имеет прямую ссылку, сборщик мусора не удаляет его. Вот пример outOfMemoryError.

public class outOfMemoryErrorExample{
    public static void main(String[] args){
        int[] integerArray = new int[1024*1024*1024];
    }
}

Для получения дополнительной информации нажмите: https://www.solutionfactory.in/posts/StackOverflowError-vs-OutOfMemoryError-in-Java

Ответ 10

StackOverflowError

  • Это связано с памятью стека.
  • Это происходит, когда стек заполнен.
  • Он выдается при вызове метода, и в стеке не осталось места.
  • Это происходит, когда вы вызываете метод рекурсивно без надлежащего завершающего условия.
  • Как избежать? Убедитесь, что методы заканчивают свое выполнение и покидают стековую память.

OutOfMemoryError

  • Это связано с кучей памяти.
  • Это происходит, когда куча заполнена.
  • Он создается при создании нового объекта, и в куче не остается свободного места.
  • Это происходит, когда вы создаете много объектов в куче памяти.
  • Как избежать? Попробуйте удалить ссылки на объекты, которые вам больше не нужны.