В чём разница между StackOverFlowError и OutOfMemoryError?
StackOverFlowError
и OutOfMemoryError
выбрасываются при недостатке памяти у jvm
, но в чём их разница?
StackOverFlowError
и OutOfMemoryError
выбрасываются при недостатке памяти у jvm
, но в чём их разница?
Эта ошибка происходит, когда переполнен стек (по-английски - stack). Если кратко, то
в стеке хранятся только ссылки на объекты, которые находятся в куче. Ещё в стеке хранятся примитивы и список методов, "кто кого вызвал". Вообщем StackOverFlowError
происходит при зацикливании вызова методов. Например:
public static void doSomething(){
doSomething();
}
При вызове метода doSomething()
произойдёт StackOverFlowError
, так как стек будет переполнен.
Чтобы исправить StackOverFlowError
нужно найти такое зацикливание и убрать его. На самом деле, вызов метода из самого себя использовать можно, но делать это стоит осторожно. Это будет называться рекурсия. Вот пример использования рекурсии для вычисления факториала:
public static int factorial(int number){
if(number < 0){
throw new IllegalArgumentException("Число меньше 0");
}
if(number == 0 || number == 1){
return 1;
}
return factorial(number - 1) * number;
}
В таком случае StackOverFlowError
не произойдёт, так как из метода в конце-концов будет выполнен выход.
В рекурсивных методах следует также проверять, что число, пришедшее в параметрах, не слишком большое. В противном случае может оказаться, что метод будет вызывать сам себя хоть и не бесконечное, но всё же достаточное количество раз, чтобы произошла ошибка StackOverFlowError
.
Это ошибка происходит, когда переполнена куча (по-английски - heap). Если кратко, то в куче хранятся объекты. Именно объекты, а не ссылки на них. То есть OutOfMemoryError
произойдёт тогда, когда в куче кончится место создавать объекты. Вот пример:
public class Test{
public static void main(String [] args){
Object[][] toManyObjects = new Object[1000000][1000000];
}
}
Этот код бует скомпилирован, но при запуске произойдёт OutOfMemoryError
:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.main(Test.java:5)
Ведь в массиве гигантское количество объектов, и в куче нет столько места.
Конечно, никто не будет делать такие глупые ошибки. Обычно OutOfMemoryError
происходит тоже при зацикливании, но не при бесконечном вызове метода, а в обычных циклах (for
, while
, do-while
), если из таких циклов нет выхода, а в теле цикла создаются какие-либо объекты.
Примеров кодов с OutOfMemoryError
масса в интернете: можете посмотреть вопросы на StackOverFlow на русском
, в которых упоминается OutOfMemoryError
, если вам интересно посмотреть в каких случаях такая ошибка может произойти.
OutOfMemoryError
происходит при переполнении кучи, а StackOverFlowError
- при переполнении стека;StackOverFlowError
происходит при бесконечном вызове метода, а
OutOfMemoryError
- при зацикливании создания объектов;Статья на хабре про память в java