В Java есть такие понятия как Heap и Stack память. Сегодня мы узнаем разницу между ними и зачем они нужны. Как всегда, сначала в теории и затем на практике разберем эту сложную тему.
Java Heap (куча) используется Java Runtime
для выделения памяти под объекты и JRE классы. Создание нового объекта также происходит в куче. Здесь работает сборщик мусора: освобождает память путем удаления объектов, на которые нет каких-либо ссылок. Любой объект, созданный в куче, имеет глобальный доступ и на него могут ссылаться с любой части приложения.
Стековая память в Java работает по схеме LIFO (Последний-зашел-Первый-вышел). Всякий раз, когда вызывается метод, в памяти стека создается новый блок, который содержит примитивы и ссылки на другие объекты в методе. Как только метод заканчивает работу, блок также перестает использоваться, тем самым предоставляя доступ для следующего метода.
Размер стековой памяти намного меньше объема памяти в куче.
Давайте рассмотрим отличия стековой памяти и кучи на примере простой программы.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package ua.com.prologistic;
public class Memory {
public static void main(String[] args) { // строка 1
int i=1; // строка 2
Object object = new Object(); // строка 3
Memory memory = new Memory(); // строка 4
memory.exMethod(object); // строка 5
} // строка 9
private void exMethod(Object param) { // строка 6
String string = param.toString(); // строка 7
System.out.println(string );
} // строка 8
}
На картинке ниже представлена память стека и кучи для программы выше
А теперь рассмотри шаги выполнения нашей программы:
main()
находит строку 1
и Java Runtime создает стековую память для использования методом main().строке 2
создается int’овая переменная, которая хранится в памяти стека метода main()
.строке 3
и он тут же появляется в куче, а стековая память содержит ссылку на него. Точно такой же процесс происходит, когда мы создаем объект Memory в строке 4
.строке 5
мы вызываем метод exMethod()
и тут же сразу создается блок на вершине стека, который будет использоваться этим методом. Поскольку Java передает параметры по значению, то в в строке 6
будет создана новая ссылка на объект, созданный в строке 3.строке 7
, отправляется в Пул строк (String Pool), который находится в куче. На эту строку также создается ссылка в стековой памяти методаexMethod()
.exMethod()
завершается на строке 8
, поэтому блок стековой памяти для этого метода становится свободным.строке 9
метод main()
завершается, поэтому стековая память для метода main()
будет уничтожена. Также программа заканчивается в этой строке, следовательно, Java Runtime освобождает всю память и завершает программу.На основании приведенных выше объяснений, мы можем легко подытожить следующие различия между Heap и Stack памятью в Java.
LIFO
.-Xms
и -Xmx
опции JVM, чтобы определить начальный и максимальный размер памяти в куче. Для стека определить размер памяти можно с помощью опции -Xss
.java.lang.StackOverflowError
, а если память кучи заполнена, то бросается исключениеjava.lang.OutOfMemoryError: Java Heap Space
.LIFO
), стековая память работает намного быстрее кучи.Вот и все, что нужно знать о Stack и Heap памяти в Java.
http://prologistic.com.ua/chto-takoe-heap-i-stack-pamyat-v-java.html
Немоного о различии Jаva и C++: https://habrahabr.ru/post/125781/