Я прочитав цю статтю про цю тему, але я не дуже її розумію. Будь ласка, дайте мені поради та приклади при описі понять.
Я прочитав цю статтю про цю тему, але я не дуже її розумію. Будь ласка, дайте мені поради та приклади при описі понять.
Відповіді:
Java надає два різні типи / класи опорних об'єктів : сильний і слабкий . Слабкі довідкові об'єкти можна далі розділити на м'які та фантомні .
Перейдемо по пункту.
Сильний довідковий об’єкт
StringBuilder builder = new StringBuilder();
Це тип / клас еталонного об'єкта за замовчуванням, якщо не вказано інакше: builder
є сильним еталонним об'єктом. Цей вид посилання робить посилається об'єкт непридатним до GC. Тобто, кожного разу, коли на об'єкт посилається ланцюг сильних довідкових об'єктів , він не може бути зібраний сміттям.
Слабкий довідковий об’єкт
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Слабкі довідкові об'єкти не є типовим типом / класом опорного об’єкта, і для їх використання вони повинні бути чітко вказані, як у вищенаведеному прикладі. Цей вид посилання робить опорний об'єкт придатним до GC. Тобто, якщо єдиною опорною досяжністю для StringBuilder
об'єкта в пам'яті є, власне, слабка посилання, тоді ГК дозволяється сміття збирати StringBuilder
об’єкт. Коли об'єкт в пам'яті є доступним лише слабким опорним об'єктам, він автоматично підходить до GC.
Рівні слабкості
Можна зарахувати два різних рівня слабкості: м'який і фантомний .
М'який Reference Object в основному слабка посилання на об'єкт , який залишається в пам'яті трохи більше: зазвичай, він чинить опір GC циклу до тих пір пам'ять не доступна , і є ризикOutOfMemoryError
(в цьому випадку, він може бути видалений).
З іншого боку, фантомний довідковий об’єкт корисний лише для того, щоб точно знати, коли об’єкт був ефективно вилучений із пам'яті: зазвичай вони використовуються для виправлення дивної фіналізованої () поведінки відродження / воскресіння , оскільки вони фактично не повертають сам об'єкт, але допомагають лише відслідковувати їхню пам'ять .
Слабкі довідкові об’єкти ідеально підходять для реалізації модулів кешу. Насправді, своєрідне автоматичне виселення може бути реалізовано, дозволяючи GC очищати області пам’яті, коли об’єкти / значення більше не доступні за допомогою сильних ланцюжків посилань. Прикладом є слабкі клавіші WeakHashMap .
Слабка довідка:
Простий посилання, простіше кажучи, - це посилання, яке недостатньо сильне, щоб змусити об'єкт залишитися в пам'яті. Слабкі посилання дозволяють використовувати можливості сміттєзбірника визначати доступність для вас, тому вам не доведеться робити це самостійно.
Посилання:
М’яке посилання точно схоже на слабку посилання, за винятком того, що менше прагнути викинути предмет, на який він посилається. Об'єкт, який є слабкодоступним (найсильніші посилання на нього - слабкі), буде викинутий у наступному циклі вивезення сміття, але об'єкт, який буде легко доступний, як правило, на деякий час буде триматися.
Посилання на фантом:
Посилання на фантоми зовсім інші, ніж SoftReference або WeakReference. Його зчеплення з об'єктом настільки немічне, що ви навіть не можете отримати об'єкт - його метод get () завжди повертається до нуля. Єдине використання для такої посилання - це відстеження, коли воно потрапляє в ReferenceQueue, оскільки в цей момент ви знаєте, що об'єкт, на який він вказував, мертвий.
Цей текст було вилучено з: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Проста різниця між ними SoftReference
і WeakReference
надається розробником Android .
Різниця між a SoftReference
і a WeakReference
- це момент часу, коли приймається рішення про очищення та запозичення посилання:
A SoftReference
слід очистити та зафіксувати його якомога пізніше, тобто у випадку, якщо ВМ загрожує втратою пам’яті.
А WeakReference
може бути ліквідований і започаткований, як тільки відомо, що він має слабкі посилання.
Три використовувані вами терміни здебільшого пов'язані з правом Об'єкта на отримання сміття.
Слабка довідка : Це посилання, яке недостатньо сильне, щоб змусити об'єкт залишитися в пам'яті. Св капризи збирача сміття , щоб зібрати цей об'єкт для збору сміття. Ви не можете змусити GC не збирати його .
М'яке посилання :: Його більш-менш схоже на слабке посилання. Але ви можете сказати, що він тримає об’єкт трохи сильніше, ніж слабке посилання від збору сміття.
Якщо збирачі сміття збирають слабку оцінку в самому першому життєвому циклі, він збиратиме м'які орієнтири в наступному циклі збору сміття.
Сильна довідка :: Її якраз протилежний до двох вищезгаданих посилань. Вони менш люблять збирати сміття (здебільшого їх ніколи не збирають).
Для отримання додаткової інформації ви можете посилатися на наступне посилання:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Ця стаття може бути дуже корисною для розуміння сильних, м'яких, слабких та фантомних посилань.
Щоб дати вам підсумок,
Якщо у вас є чітка довідка на об'єкт, GC (Garbage Collector) ніколи не може бути зібраний / відшкодований.
Якщо у вас є лише слабкі посилання на об'єкт (без чітких посилань), GC об'єкт буде відтворений в наступному циклі GC.
Якщо у вас є лише м'які посилання на об'єкт (без чітких посилань), GC об'єкт буде відтворений лише тоді, коли у JVM не вистачає пам'яті.
Ми створюємо фантомні посилання на об’єкт, щоб відстежувати, коли об’єкт потрапляє в ReferenceQueue
. Коли ви знаєте, що ви можете виконати дрібнозернисту доопрацювання (Це врятувало б вас від випадкового відродження об'єкта, оскільки фантомна довідка не дає вам реферату). Я б запропонував вам прочитати цю статтю, щоб отримати детальну інформацію про це.
Тож можна сказати, що міцні посилання мають вищу силу (ніколи не може бути зібрана GC)
М'які посилання є потужними, ніж слабкі посилання (оскільки вони можуть уникнути циклу GC, поки у JVM не закінчиться пам'ять)
Слабкі посилання є навіть менш потужними, ніж м'які посилання (оскільки вони не можуть уникнути жодного циклу GC і будуть відшкодовані, якщо об'єкт не має інших сильних посилань).
Аналогія ресторану
Тепер, якщо ви сильний клієнт (аналогічним сильним посиланням), то навіть якщо в ресторан завітає новий клієнт або він так радує, ви ніколи не покинете свій стіл (область пам'яті на купі). Офіціант не має права сказати вам (або навіть просити вас) покинути ресторан.
Якщо ви м'який замовник (аналог м'якого посилання), то якщо в ресторан приїде новий клієнт, офіціант не попросить вас покинути стіл, якщо не залишиться іншого порожнього столу для розміщення нового клієнта. (Іншими словами, офіціант попросить вас залишити стіл лише у тому випадку, якщо новий клієнт вступить, а для цього нового клієнта не залишилося іншої таблиці)
Якщо ви слабкий клієнт (аналогічно слабкому посиланням), то офіціант за його бажанням може (у будь-який момент часу) попросити вас покинути ресторан: P
4 ступінь відліку - Strong, Weak, Soft, Phantom
Сильний - це вид посилання, який робить посилається об'єкт непридатним до GC. класи будівельників. наприклад - StringBuilder
Слабкий - це довідка, яка підходить для GC.
Soft - це вид посилання, об'єкт якого підходить для GC, поки не буде доступна пам'ять. Найкраще для кешу зображень. Він буде тримати їх, поки не буде доступна пам'ять.
Phantom - це різновид посилання, об’єкт якого безпосередньо відповідає ГК. Використовується лише для того, щоб знати, коли об’єкт вилучається з пам'яті.
використовує:
Дозволяє ідентифікувати, коли об’єкт точно видалений із пам'яті.
коли
finalize()
метод перевантажений, GC може не статися вчасно для об'єктів, що відповідають вимогам GC, двох класів. Тож посилання на фантоми робить їх прийнятними до GC ранішеfinalize()
, тому ви можете отримати OutOfMemoryErrors навіть тоді, коли більша частина купи сміття.
Слабкі посилання ідеально підходять для реалізації модулів кешу.
Це ваші звичайні посилання на об'єкти, які ми кодуємо щодня:
Employee emp = new Employee();
Змінна “emp” має чітке посилання на об’єкт Employee, а об’єкти, доступні через будь-яку ланцюжок чітких посилань, не підлягають збору сміття. Зазвичай це те, що ви хочете, але не завжди. Тепер припустимо, що ми збираємо багато співробітників з бази даних у колекції чи карті, і нам потрібно регулярно проводити багато обробки, тому для збереження продуктивності ми збережемо їх у кеші.
Наскільки це добре, але зараз нам потрібні різні дані, і нам не потрібні ці об'єкти Співробітника, і на них не посилаються ніде, крім кешу. Що спричиняє витік пам’яті, оскільки ці об’єкти не використовуються, але все ще не мають права на збір сміття, і ми не можемо вилучити ці об’єкти з кешу, оскільки ми не маємо на них посилання? Тому тут або нам потрібно спорожнити весь кеш вручну, що втомлює, або ми могли використовувати інші посилання, наприклад, слабкі посилання.
Слабка посилання не закріплює об'єкт у пам'яті і буде GC'd у наступному циклі GC, якщо не посилається на інші посилання. Ми можемо використовувати клас WeakReference, який надає Java, для створення кешів вище виду, які не зберігатимуть об'єкти, на які не посилаються з іншого місця.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Для доступу до даних вам потрібно зателефонувати cache.get (). Цей виклик отримати може повернути нуль, якщо слабке посилання було зібрано сміття: ви повинні перевірити повернене значення, щоб уникнути NPE. Java надає колекції, які використовують слабкі посилання, наприклад, клас WeakHashMap зберігає ключі (а не значення) як слабкі посилання. Якщо ключ - GC'd, значення автоматично також буде видалено з карти.
Оскільки слабкі посилання теж є об’єктами, нам потрібен спосіб їх очищення (вони більше не корисні, коли об’єкт, на який вони посилалися, був GC'd). Якщо ви передасте ReferenceQueue в конструктор для слабкої посилання, тоді сміттєзбірник додасть це слабке посилання на ReferenceQueue до їх завершення або GC'd. Ви можете періодично обробляти цю чергу і мати справу з мертвими посиланнями.
SoftReference подібний до WeakReference, але рідше збирається сміття. М'які посилання видаляються на розсуд сміттєзбірника у відповідь на вимогу пам'яті. Віртуальна машина гарантує, що всі м'які посилання на м'якодоступні об'єкти будуть очищені до того, як вона коли-небудь викине OutOfMemoryError.
Посилання на фантоми є найслабшими з усіх типів посилань, дзвінки на них завжди повертатимуться в нулеві. На об'єкт посилається фантомно після його остаточного завершення, але перед тим, як виділена пам'ять була відтворена, на відміну від слабких посилань, які запускаються до їх завершення, або посилання GC'd Phantom рідко використовуються.
То чим вони корисні? Коли ви будуєте посилання на фантом, ви завжди повинні проходити в черзі ReferenceQue. Це вказує на те, що ви можете використовувати фантомну посилання, щоб побачити, коли ваш об’єкт є GC'd.
Привіт, тому якщо слабкі посилання будуть зафіксовані, коли вони вважаються завершеними, але ще не є GC'd, ми могли б створити нове чітке посилання на об'єкт у блоці фіналізатора і запобігти GC'd об'єкта. Так, ви можете, але ви, мабуть, не повинні цього робити. Для перевірки на цей випадок цикл GC відбудеться щонайменше двічі для кожного об'єкта, якщо тільки цей об'єкт недоступний лише посиланням на фантом. Ось чому ви можете вичерпати купу навіть тоді, коли у вашій пам’яті міститься багато сміття. Фантомні посилання можуть запобігти цьому.
Ви можете прочитати більше в моїй статті Типи посилань на Java (Сильна, М'яка, Слабка, Фантомна) .