JavaRush /Java блог /Random UA /Відмінності між слабкими, м'якими, фантомними та звичайни...
theGrass
24 рівень
Саратов

Відмінності між слабкими, м'якими, фантомними та звичайними посиланнями в Java

Стаття з групи Random UA
«Слабкі» посилання та «м'які» посилання (WeakReference, SoftReference) були додані в Java API давно, але не кожен програміст знайомий з ними. Це свідчить про прогалину в розумінні, де і як їх використовувати. Посилальні класи особливо важливі в контексті складання сміття . Як всі ми знаємо збирач сміття сам звільняє пам'ять займану об'єктами, але не всі програмісти знають, що рішення про звільнення пам'яті він приймає виходячи з типу посилань, що є на об'єкт. Відмінності між слабкими, м'якими, фантомними та звичайними посиланнями в Java - 1Головна відмінність SoftReference від WeakReference у тому, як збирач з ними працюватиме. Він може видалити об'єкт у будь-який момент, якщо на нього вказують тільки weak посилання, з іншого боку об'єкти з soft посиланням будуть зібрані тільки коли JVMдуже потрібна пам'ять. Завдяки таким особливостям класів посилань кожен з них має своє застосування. SoftReference можна використовувати для реалізації кешів і коли JVM знадобиться пам'ять, вона звільнить її за рахунок видалення таких об'єктів. А WeakReference відмінно підійдуть для зберігання метаданих, наприклад, для зберігання посилання на ClassLoader. Якщо немає класів для завантаження, то немає сенсу зберігати посилання на ClassLoader , слабке посилання робить ClassLoader доступним для видалення, як тільки ми призначимо його замість міцного посилання (Strong reference). У цій статті ми розглянемо відмінності типів посилань, у тому числі Strong reference та Phantom reference (фантомне посилання).

WeakReference vs SoftReference в Java

Для тих хто не знає є 4 види посилань:
  1. Strong reference
  2. Weak Reference
  3. Soft Reference
  4. Phantom Reference
Strong посилання найпростіше, тому що ми використовуємо її в програмуванні день у день, наприклад в коді виду String s = "abc" змінна s це і є strong посилання. Будь-який об'єкт що має strong посилання заборонений для видалення збирачем сміття. Очевидно що це об'єкти які необхідні Java програмі. Слабкі посилання представлені класом java.lang.ref.WeakReference , ви можете визначити слабке посилання так:
Counter counter = new Counter(); // strong reference
WeakReference weakCounter = new WeakReference(counter); //weak reference
counter = null; // now Counter object is eligible for garbage collection
Тепер, як тільки ви надали strong посилання counter значення null (counter = null), той об'єкт що створений в першому рядку стає доступним для видалення збирачем сміття, тому що він більше не має strong посилання. Створена Weak посилання weakCounter не може запобігти видаленню збирачем об'єкта Counter. З іншого боку якби це було Soft посилання, об'єкт типу Counter не був би видалений до тих пір, поки JVM не потребувала б пам'яті особливо сильно. Soft посилання в Java представлені класом java.lang.ref.SoftReference . Приклад створення SoftReference в Java
Counter prime = new Counter();  // prime holds a strong reference
SoftReference soft = new SoftReference(prime) ; //soft reference variable has SoftReference to Counter Object
prime = null;  // now Counter object is eligible for garbage collection but only be collected when JVM absolutely needs memory
Після обнулення strong посилання (у 3-му рядку) на об'єкт Counter залишиться тільки 1 м'яке посилання, яке не зможе запобігти видаленню цього об'єкта збирачем сміття, але на відміну від weak посилання зможе відкласти цей процес до тих пір, поки не з'явиться гостра нестача пам'яті. З огляду на цю відмінність soft посилання від weak, перша більше підходить для кешів, а weak для метаданих. Хорошим прикладом служить клас WeakHashMap, який є спадкоємцем інтерфейсу Map як і класи HashMap або TreeMap , але з однією відмінністю. WeakHashMap обертає ключі як weak посилання, що означає що як тільки не залишилося strong посилань на об'єкт, weak посилання які розташовані всередині WeakHashMapне врятують від збирача сміття. Фантомні посилання – третій тип посилань, доступних у пакеті java.lang.ref. Phantom посилання представлені класом java.lang.ref.PhantomReference . Об'єкт на який вказують тільки phantom посилання може бути видалений збирачем будь-якої миті. Phantom посилання створюється так само як weak або soft.
DigitalCounter digit = new DigitalCounter(); // digit reference variable has strong reference
PhantomReference phantom = new PhantomReference(digit); // phantom reference
digit = null;
Як тільки ви обнулите сильні посилання на об'єкт DigitalCounter, збирач сміття видалить його в будь-який момент, тому що тепер на нього ведуть тільки фантом посилання. Крім класів WeakReference, SoftReference, PhantomReference, WeakHashMap, корисно знати про клас ReferenceQueue . Ви можете скористатися цим класом під час створення об'єкта класу WeakReference, SoftReference або PhantomReference:
ReferenceQueue refQueue = new ReferenceQueue(); //reference will be stored in this queue for cleanup
DigitalCounter digit = new DigitalCounter();
PhantomReference phantom = new PhantomReference(digit, refQueue);
Посилання на об'єкт буде додано до ReferenceQueue і ви зможете контролювати стан посилань шляхом опитування ReferenceQueue. Життєвий цикл Object добре представлений на цій діаграмі: Відмінності між слабкими, м'якими, фантомними та звичайними посиланнями в Java - 2Ось і всі відмінності між weak і soft посиланнями Java . Також ми познайомабося з phantom посиланнями, класом WeakHashMap і ReferenceQueue . Правильне використання посилань допоможе при складанні сміття і в результаті ми отримаємо гнучкіше управління пам'яттю в Java . Оригінал статті
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ