Что такое память стека?
Стек в Java — это раздел памяти, который содержит методы, локальные переменные и ссылочные переменные. Память стека всегда указывается в порядке «последний пришел первым — вышел». Локальные переменные создаются в стеке.
Что такое кучная память?
Куча — это раздел памяти, который содержит объекты и может также содержать ссылочные переменные. Переменные экземпляра создаются в куче
Распределение памяти в Java
JVM разделил память на следующие разделы.
- отвал
- стек
- Код
- статический
Такое разделение памяти требуется для его эффективного управления.
- Раздел кода содержит ваш байт-код .
- Раздел стека памяти содержит методы, локальные переменные и ссылочные переменные.
- Раздел Heap содержит объекты (может также содержать ссылочные переменные).
- Статический раздел содержит статические данные / методу .
Разница между локальной переменной и переменной экземпляра
Переменная экземпляра объявлена внутри класса, но не внутри метода
class Student{ int num; // num is instance variable public void showData{}
Локальная переменная объявляются в виде метода , включая метод аргументов .
public void sum(int a){ int x = int a + 3; // a , x are local variables; }
Разница между стеком и кучей
Нажмите здесь, если видео не доступно
Давайте рассмотрим пример, чтобы лучше это понять.
Учтите, что ваш основной метод вызывает метод m1
public void m1{ int x=20 }
В стеке java фрейм будет создан из метода m1.
Переменная X в m1 также будет создана в кадре для m1 в стеке. (См. Изображение ниже).
Метод m1 вызывает метод m2. В стеке Java создается новый кадр для m2 поверх кадра m1.
Переменные b и c также будут созданы в кадре m2 в стеке.
public void m2(int b){ boolean c; }
Тот же метод m2 вызывает метод m3. Снова кадр m3 создается на вершине стека (см. Изображение ниже).
Теперь допустим, что наш метод m3 создает объект для класса «Account», который имеет переменные двух экземпляров int p и int q.
Account { Int p; Int q; }
Вот код для метода м3
public void m3(){ Account ref = new Account(); // more code }
Оператор new Account () создаст объект учетной записи в куче.
Ссылочная переменная «ref» будет создана в стеке Java.
Оператор присваивания «=» создаст ссылочную переменную для указания на объект в куче.
Как только метод завершил свое выполнение. Поток управления вернется к вызывающему методу. Который в этом случае является методом m2.
Стек из метода m3 будет очищен.
Поскольку ссылочная переменная больше не будет указывать на объект в куче, она будет иметь право на сборку мусора.
После того, как метод m2 завершил свое выполнение. Он будет извлечен из стека, и все его переменные будут сброшены и больше не будут доступны для использования.
Аналогично для метода m1.
В конце концов поток управления вернется в начальную точку программы. Который обычно является «основным» методом.
Что если Object имеет ссылку в качестве переменной экземпляра?
public static void main(String args[]) { A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d; //more code }
В этом случае ссылочная переменная child будет создана в куче, которая, в свою очередь, будет указывать на свой объект, что-то вроде диаграммы, показанной ниже.
Резюме:
- Когда вызывается метод, в верхней части стека создается фрейм.
- Как только метод завершил выполнение, поток управления возвращается к вызывающему методу, и соответствующий ему кадр стека сбрасывается.
- Локальные переменные создаются в стеке
- Переменные экземпляра создаются в куче и являются частью объекта, которому они принадлежат.
- Ссылочные переменные создаются в стеке.