Heap и Stack память в Java

В Java есть такие понятия как Heap и Stack память. Сегодня мы узнаем разницу между ними и зачем они нужны. Как всегда, сначала в теории и затем на практике разберем эту сложную тему.

Java Heap память

Java Heap (куча) используется Java Runtime для выделения памяти под объекты и JRE классы. Создание нового объекта также происходит в куче. Здесь работает сборщик мусора: освобождает память путем удаления объектов, на которые нет каких-либо ссылок. Любой объект, созданный в куче, имеет глобальный доступ и на него могут ссылаться с любой части приложения.

Stack память в Java

Стековая память в 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


}

На картинке ниже представлена память стека и кучи для программы выше

А теперь рассмотри шаги выполнения нашей программы:

    1. Как только мы запустим программу, загружаются все классы среды выполнения в кучу. Потом метод main()находит строку 1 и Java Runtime создает стековую память для использования методом main().
    2. Далее в строке 2 создается int’овая переменная, которая хранится в памяти стека метода main().
    3. Потом мы создали объект в строке 3 и он тут же появляется в куче, а стековая память содержит ссылку на него. Точно такой же процесс происходит, когда мы создаем объект Memory в строке 4.
    4. Теперь в строке 5 мы вызываем метод exMethod() и тут же сразу создается блок на вершине стека, который будет использоваться этим методом. Поскольку Java передает параметры по значению, то в в строке 6 будет создана новая ссылка на объект, созданный в строке 3.
    5. Строка, созданная в строке 7, отправляется в Пул строк (String Pool), который находится в куче. На эту строку также создается ссылка в стековой памяти методаexMethod().
    6. Метод exMethod()завершается на строке 8, поэтому блок стековой памяти для этого метода становится свободным.
    7. В строке 9 метод main() завершается, поэтому стековая память для метода main()будет уничтожена. Также программа заканчивается в этой строке, следовательно, Java Runtime освобождает всю память и завершает программу.

Разница между Stack и Heap памятью в Java

На основании приведенных выше объяснений, мы можем легко подытожить следующие различия между Heap и Stack памятью в Java.

    • Куча используется всеми частями приложения в то время как стек используется только одним потоком исполнения программы.
    • Всякий раз, когда создается объект, он всегда хранится в куче, а в памяти стека содержится ссылка на него. Память стека содержит только локальные переменные примитивных типов и ссылки на объекты в куче.
    • Объекты в куче доступны с любой точки программы, в то время как стековая память не может быть доступна для других потоков.
    • Управление памятью в стеке осуществляется по схеме LIFO.
    • Стековая память существует лишь какое-то время работы программы, а память в куче живет с самого начала до конца работы программы.
    • Мы можем использовать -Xms и -Xmx опции JVM, чтобы определить начальный и максимальный размер памяти в куче. Для стека определить размер памяти можно с помощью опции -Xss .
    • Если память стека полностью занята, то Java Runtime бросает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/