top of page

Heap і Stack.

Stack (Стек)


- Стекова пам'ять у Java використовується для виділення статичної пам'яті й виконання потоків.

Стек містить примітивні локальні значення методів й посилання на об'єкти, що знаходяться в купі.


- Доступ до пам'яті здійснюється в порядку LIFO (Last-In-First-Out). Коли ми викликаємо новий метод, новий блок створюється поверх стеку, що містить значення, що характерні для цього методу, такі як примітивні змінні й посилання на об'єкти.


- Коли метод завершує виконання, відповідний stack frame (стековий кадр - механізм передавання аргументів і виділення тимчасової пам'яті) скидається, потік повертається до методу, що викликається і звільняється місце для наступного методу.


Ключові особливості стекової пам'яті (стеку):

- Стек збільшується й зменшується по мірі виклику й повернення нових методів відповідно;

- Змінні всередині стеку існують лише до тих пір, поки працює метод, що їх створив;

- Стек автоматично виділяється й звільняється коли метод завершує виконання;

- Якщо стекова пам'ять заповнена, Java видає помилку java.lang.StackOverFlowError;

- Доступ до стекової пам'яті швидший, порівняно з купою (heap).

- Стекова пам'ять є потокобезпечною, оскільки кожен потік працює в своєму окремому стекові (під кожен потік виділяється окремий стек).


Heap (Купа)


- Купа (heap) використовується для динамічного виділення пам'яті для об'єктів Java і класів JRE під час виконання програми. Нові об'єкти завжди створюються в купі (heap), а посилання на ці об'єкти містяться в стеці (stack).


- Ці об'єкти Java мають глобальний доступ і ми можемо отримати до них доступ з будь-якої точки нашого додатку.


- Ми можемо розбити цю модель пам'яті на менші частини, які ми умовно називатимемо "поколіннями":

- Young Generation - тут містяться і старіють усі нові об'єкти. Незначна збірка сміття відбувається, коли він заповнюється.

- Old or Tenured Generation - тут зберігаються об'єкти-довгожителі. Коли об'єкти зберігаються в молодому поколінні, встановлюється поріг віку об'єкту й коли цей поріг досягається, об'єкт переміщується до старого покоління.

- Permanent Generation - складається з метаданих JVM для класів середовища виконання й методів додатку.

- Ми завжди можемо маніпулювати розміром пам'яті купи у відповідності з нашими вимогами.


Ключові особливості пам'яті купи (heap):

- Доступ до купи здійснюється за допомогою складних методі керування пам'яттю, що містять у собі "Молоде Покоління", "Старе Покоління", "Постійне Покоління".


- Якщо місце в купі заповнене, Java видає помилку java.lang.OutOfMemoryError.


- Доступ до цієї пам'яті повільніший, порівняно з доступом до пам'яті стеку.


- Пам'ять купи (heap) не звільняється автоматично, на відміну від стеку. Купі потрібен збирач сміття аби звільняти об'єкти, що не використовуються, задля ефективності використовування пам'яті.


- На відміну від стеку, купа не є потокобезпечною й повинна бути захищеною шляхом правильної синхронізації коду.


Приклад


Для прикладу проаналізуємо фрагмент Java-коду аби оцінити як тут можна керувати пам'яттю:


class Person {

int id;

String name;


public Person(int id, String name) {

this.id = id;

this.name = name;

}

public class PersonBuilder {

private static Person buildPerson(int id, String name) {

return new Person(id, name);

}


public static void main(String[] args) {

int id = 23;

String name = "John";

Person person = null;

person = buildPerson(id, name);

}

}


Проаналізуємо код крок за кроком:

1. Коли ми входимо до методу main(), у стекові створюється простір для зберігання примітивних типів даних і посилання цього методу.

- Пам'ять стеку напряму зберігає примітивне значення цілочисельного ідентифікатора.

- Також у пам'яті стеку буде створена посиланнєва змінна person типу (класу) Person, яка вказуватиме на реальний об'єкт у купі (heap).

2. Виклик параметризованого конструктора Person(int, String) з main() виділить додаткову пам'ять поверх попереднього стеку. Це міститиме:

- посилання на об'єкт this, що викликає об'єкт у пам'яті стеку.

- значення примітивного типу id в пам'яті стеку.

- посиланнєва змінна типу String, яка називається name, котра вказуватиме на фактичний рядок з пулу рядків у купі (heap).

3. Основний метод - подальший виклик статичного методу buildPerson(), для якого подальше виділення пам'яті відбуватиметься в пам'яті стеку поверх попереднього. Це знову збереже змінні в порядку, що описаний вище.

4. Однак у пам'яті купи зберігатимуться всі змінні екземпляру для знову створеного об'єкта person типу Person.




Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
bottom of page