Керування пам'яттю в Java
Що таке стекова пам'ять?
Стек у java — це частина пам’яті, яка містить методи, локальні змінні та змінні-посилання. Пам’ять стека завжди посилається в порядку «останній прийшов-перший вийшов». Локальні змінні створюються в стеку.
Що таке оперативна пам'ять?
Купа — це ділянка пам’яті, яка містить об’єкти, а також може містити посилальні змінні. Змінні екземпляра створюються в купі.
Розподіл пам'яті в Java
Розподіл пам'яті в Java це процес, у якому секції віртуальної пам'яті відкладаються в програмі для зберігання змінних і екземплярів структур і класів. Однак пам’ять не виділяється об’єкту під час оголошення, а створюється лише посилання. Для розподілу пам'яті об'єкта використовується метод new(), тому об'єкт завжди виділяє пам'ять у купі.
Команда Java Розподіл пам'яті розділено на такі розділи:
- купа
- Стек
- код
- Статичний
Такий розподіл пам'яті необхідний для ефективного управління нею.
- Команда код розділ містить ваші байт-код.
- Команда Стек розділ пам'яті містить методи, локальні змінні та довідкові змінні.
- Команда купа розділ містить Об'єкти (може також містити посилальні змінні).
- Команда Статичний розділ містить Статичні дані/методи.
Різниця між локальною та змінною екземпляра
Змінна інстанція оголошено всередині класу, але не всередині методу
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.
Змінна 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; }
Ось код методу m3
public void m3(){ Account ref = new Account(); // more code }
Інструкція new Account() створить об’єкт 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» буде створено в купі, яка, у свою чергу, вказуватиме на свій об’єкт, щось на зразок діаграми, показаної нижче.
У чому полягає збір сміття 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.
Основна інформація:
- Під час виклику методу у верхній частині стека створюється рамка.
- Після завершення виконання методу потік керування повертається до викликаного методу, а його відповідний кадр стека скидається.
- Локальні змінні створюються в стеку
- Змінні екземпляра створюються в купі та є частиною об’єкта, якому вони належать.
- Довідкові змінні створюються в стеку.