1. Слабкі посилання в Java

У Java є кілька видів посилань.

Є StrongReference — це звичайні посилання, які ми створюємо щодня.


Object object = new Object();//создал обьект
object = null;//тепер може бути зібраний збирачем сміття

І є три "особливі" типи посилань — SoftReference, WeakReference, PhantomReference. По суті, різниця між усіма типами посилань лише одна — поведінка GC з об'єктами, на які вони посилаються. Ми детальніше обговоримо особливості кожного типу посилань пізніше, а поки що буде достатньо цих знань:

  • SoftReference — м'яке посилання; якщо GC бачить, що об'єкт доступний лише через ланцюжок soft-посилань, він видалить його з пам'яті. Мабуть.
  • WeakReference — слабке посилання; якщо GC бачить, що об'єкт доступний лише через ланцюжок weak-посилань, він видалить його з пам'яті.
  • PhantomReference — фантомне посилання; якщо GC бачить, що об'єкт доступний лише через ланцюжок phantom-посилань, він його видалить із пам'яті. Після кількох запусків GC.

Також можна сказати, що типи посилань мають певний ступінь м'якості:

  • Звичайне жорстке посилання – будь-яка змінна типу посилання. Очиститься збирачем сміття не раніше, ніж перестане використовуватися.
  • SoftReference. Об'єкт не стане причиною витрати всієї пам'яті – гарантовано буде видалено до виникнення OutOfMemoryError. Можливо раніше, залежить від реалізації збирача сміття.
  • WeakReference. Слабкіша за м'яку. Не запобігає утилізації об'єкта, збирач сміття ігнорує такі посилання.
  • PhantomReference. Використовується для “передсмертної” обробки об'єкта: об'єкт доступний після фіналізації, доки не очищений збирачем сміття.

Якщо поки що не зрозуміло, в чому ж різниця, не переживай: скоро все стане на свої місця. Дрібниці у деталях, а деталі будуть далі.

2. WeakReference та SoftReference у Java

Для початку розглянемо різницю між WeakReference і SoftReference в Java.

Якщо коротко, збирач сміття звільнить пам'ять об'єкта, якщо на нього вказують лише слабкі посилання. Якщо на об'єкт вказують посилання SoftReferences, то звільнення пам'яті відбувається, коли JVM дуже потребує пам'яті.

Це дає певну перевагу SoftReference перед Strong посиланням у певних випадках. Наприклад, SoftReference використовують для реалізації кешу додатків, тому JVM насамперед вилучить об'єкти, на які вказують лише SoftReferences.

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

Приклад WeakReference в Java:


// якийсь об'єкт
Student student = new Student();

// слабке посилання на нього
WeakReference weakStudent = new WeakReference(student);

// тепер об'єкт Student можна забрати збирачем сміття
student = null;

Пример SoftReference в Java:


// якийсь об'єкт
Student student = new Student();

// слабке посилання на нього
SoftReference softStudent = new SoftReference(student)

// тепер об'єкт Student можна забрати збирачем сміття
// але це трапиться лише в разі сильної потреби JVM у пам'яті
student = null;

3. Посилання PhantomReference у Java

Примірник PhantomReference створюється так само, як і на прикладах WeakReference та SoftReference, але використовується він досить рідко.

PhantomReference може бути зібрана збирачем сміття, якщо на об'єкт нема сильних (Strong), слабких (WeakReference) або м'яких (SoftReference) посилань.

Ти можеш створити об'єкт Phantom Reference таким чином:


PhantomReference myObjectRef = new PhantomReference(MyObject);

PhantomReference може використовуватися в ситуаціях, коли використання finalize() не має сенсу. Цей тип посилань відрізняється від інших типів, оскільки він не призначений для доступу до об'єкта. Він є сигналом про те, що об'єкт уже фіналізований, і збирач сміття готовий повернути свою пам'ять.

Для цього збирач сміття розмыщуэ його в спеціальний ReferenceQueue для подальшої обробки. ReferenceQueue — це місце, куди розміщуються посилання на об'єкти для звільнення пам'яті.

Фантомні посилання — це безпечний спосіб дізнатися, що об'єкт видалено з пам'яті. Наприклад, розглянемо програму, яка має справу з великими зображеннями. Припустимо, ми хочемо завантажити зображення до пам'яті, коли воно вже знаходиться в пам'яті, яка готова до складання сміття. У цьому випадку ми хочемо почекати, поки збирач сміття вб'є старе зображення і лише потім завантажувати в пам'ять нове.

Тут PhantomReference є гнучким та безпечним вибором. Посилання на старе зображення передасться до ReferenceQueue після знищення старого об'єкта зображення. Отримавши це посилання, ми можемо завантажити нове зображення на згадку.

undefined
3
Опрос
null,  18 уровень,  7 лекция
недоступен
null
Робота з пам'яттю в Java