Что такое Heap и Stack память в Java?

Что такое Heap и Stack память в Java?

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

Java Heap память

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

Stack память в Java

Стековая память в Java работает по схеме LIFO (Последний-зашел-Первый-вышел). Всякий раз, когда вызывается метод, в памяти стека создается новый блок, который содержит примитивы и ссылки на другие объекты в методе. Как только метод заканчивает работу, блок также перестает использоваться, тем самым предоставляя доступ для следующего метода.
Размер стековой памяти намного меньше объема памяти в куче.

Давайте рассмотрим отличия стековой памяти и кучи на примере простой программы.

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

Java Heap Java Stack - javadevblog.com

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

  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. Следите за обновлениями в разделе Полезности.

6 Комментарии “Что такое Heap и Stack память в Java?

  1. Вечер добрый! У вас есть в коде присутствует ошибка, из-за чего возможно затруднение понимания начинающими программистами.
    Ваша строка
    mem.exMethod(obj);
    заменяется на
    memory.exMethod(object);

  2. Stack — это часть Permanent Generation (а начиная с java 8 — часть Metaspace ), верно? или я неправильно понимаю?

  3. Опечатка в строке «Поскольку Java передает параметры по значению». Объекты передаются по ссылке, а примитивы по значению. В примере передается объект, соответственно по ссылке.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *