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
}
На картинке ниже представлена память стека и кучи для программы выше
А теперь рассмотри шаги выполнения нашей программы:
- Как только мы запустим программу, загружаются все классы среды выполнения в кучу. Потом метод
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 освобождает всю память и завершает программу.
Разница между 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/