Управление памятью в Java

Что такое стековая память?

Стек в Java — это раздел памяти, который содержит методы, локальные переменные и ссылочные переменные. К памяти стека всегда обращаются в порядке «последним пришел — первым обслужен». Локальные переменные создаются в стеке.

Что такое динамическая память?

Куча — это раздел памяти, который содержит объекты и может также содержать ссылочные переменные. Переменные экземпляра создаются в куче.

Распределение памяти в Java

Распределение памяти в Java — это процесс, при котором в программе выделяются разделы виртуальной памяти для хранения переменных и экземпляров структур и классов. Однако при объявлении объекту не выделяется память, а создается только ссылка. Для выделения памяти объекта используется метод new(), поэтому объекту всегда выделяется память в куче.

Территория Java Распределение памяти разделено на следующие разделы:

  1. куча
  2. Стек
  3. Code
  4. статический

Такое разделение памяти необходимо для эффективного управления ею.

  • Территория код раздел содержит ваши байткодом.
  • Территория Стек раздел памяти содержит методы, локальные переменные и ссылочные переменные.
  • Территория куча раздел содержит Объекты (также может содержать ссылочные переменные).
  • Территория статический раздел содержит Статические данные/методы.

Разница между локальной переменной и переменной экземпляра

Переменная экземпляра объявлен внутри класса, но не внутри метода

class Student{ 
int num; // num is  instance variable 
public void showData{}

Локальная переменная объявлены внутри a метод, включающий метод Аргументы.

public void sum(int a){

int x = int a +  3;

// a , x are local variables;

}

Разница между стеком и кучей

Нажмите здесь если видео недоступно

Давайте рассмотрим пример, чтобы лучше понять это. Предположим, что ваш основной метод вызывает метод m1

public void m1{
int x=20
}

В стеке Java кадр будет создан методом m1.

Java Стек и куча

Переменная X в m1 также будет создана в кадре для m1 в стеке. (См. изображение ниже).

Java Стек и куча

Метод m1 вызывает метод m2. В стеке Java создается новый кадр для m2 поверх кадра m1.

Java Стек и куча

Java Стек и куча

Переменные b и c также будут созданы в кадре m2 в стеке.

public void m2(int b){
boolean c;
}

Java Стек и куча

Тот же метод m2 вызывает метод m3. Снова создается кадр m3 на вершине стека (см. изображение ниже).

Java Стек и куча

Java Стек и куча

Теперь предположим, что наш метод m3 создает объект для класса «Account», который имеет два переменная экземпляров int p и int q.

Account {
             Int p;
             Int q;
       }

Вот код метода m3

public void m3(){
	Account ref = new Account();
	// more code
}

Оператор new Account() создаст объект аккаунта в куче.

Java Стек и куча

Ссылочная переменная «ref» будет создана в стеке java.

Java Стек и куча

Оператор присваивания «=» создаст ссылочную переменную, указывающую на объект в куче.

Java Стек и куча

После того, как метод завершит свое выполнение, поток управления вернется к вызывающему методу. В данном случае это метод m2.

Java Стек и куча

Стек метода m3 будет очищен.

Java Стек и куча

Поскольку ссылочная переменная больше не будет указывать на объект в куче, ее можно будет использовать для сборки мусора.

Java Стек и куча

После того, как метод 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» будет создана в куче, которая, в свою очередь, будет указывать на свой объект, как показано на диаграмме ниже.

Java Стек и куча

Что такое сбор мусора Java?

Сбор мусора в Java — это процесс, посредством которого программы автоматически выполняют управление памятью. Сборщик мусора (GC) находит неиспользуемые объекты и удаляет их, чтобы освободить память. В Javaдинамическое выделение памяти объектам достигается с помощью оператора new, который использует часть памяти, и память остается выделенной до тех пор, пока не появятся ссылки на использование объекта.

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

Техника, позволяющая добиться этого, известна как Вывоз мусора. Программы, которые не освобождают память, могут в конечном итоге выйти из строя, если в системе не останется памяти для выделения. Говорят, что эти программы имеют утечки памяти. Сбор мусора в Java происходит автоматически во время жизни программы, что устраняет необходимость освобождать память и тем самым позволяет избежать утечек памяти.

В языке C ответственность за освобождение памяти, выделенной динамически, с помощью функции free() лежит на программисте. Вот где Java ведет управление памятью.

Примечание: Все объекты создаются в разделе Heap памяти. Подробнее об этом в следующем уроке.

Пример: изучить механизм сборщика мусора в Java

Шаг 1) Скопируйте следующий код в редактор.

class Student{
int a;
int b;
  public void setData(int c,int d){
    a=c;
    b=d;
  }
  public void showData(){
    System.out.println("Value of a = "+a);
    System.out.println("Value of b = "+b);
  }
  public static void main(String args[]){
    Student s1 = new Student();
    Student s2 = new Student();
    s1.setData(1,2);
    s2.setData(3,4);
    s1.showData();
    s2.showData();
    //Student s3;
    //s3=s2;
    //s3.showData();
    //s2=null;
    //s3.showData();
    //s3=null;
    //s3.showData();
  }
}

Шаг 2) Сохраните, скомпилируйте и запустите код. Как показано на схеме, создаются два объекта и две ссылочные переменные.


Механизм сборщика мусора

Шаг 3) Раскомментируйте строки №20,21,22. Сохраните, скомпилируйте и запустите код.

Шаг 4) Как показано на диаграмме ниже, две ссылочные переменные указывают на один и тот же объект.

Механизм сборщика мусора

Шаг 5) Раскомментируйте строки № 23 и 24. Скомпилируйте, сохраните и запустите код.

Шаг 6) Как показано на диаграмме ниже, s2 становится нулевым, но s3 по-прежнему указывает на объект и не подлежит сборке мусора Java.

Механизм сборщика мусора

Шаг 7) Раскомментируйте строки № 25 и 26. Сохраните, скомпилируйте и запустите код.

Шаг 8) На этом этапе нет ссылок, указывающих на объект, и он становится пригодным для сборки мусора. Оно будет удалено из памяти, и вернуть его обратно невозможно.

Изучите сборщик мусора

Как удалить объект в Java?

1) Если вы хотите, чтобы ваш объект имел право на сбор мусора, присвойте его ссылочной переменной значение null.

2) Примитивные типы не являются объектами. Им не может быть присвоено значение null.

Как удалить объект в Java

Резюме:

  • При вызове метода на вершине стека создается кадр.
  • После завершения выполнения метода поток управления возвращается к вызывающему методу, и соответствующий ему кадр стека очищается.
  • Локальные переменные создаются в стеке
  • Переменные экземпляра создаются в куче и являются частью объекта, которому они принадлежат.
  • Справочные переменные создаются в стеке.