Java: разница между сильной / мягкой / слабой / фантомной ссылкой - PullRequest
157 голосов
/ 21 марта 2012

Я прочитал эту статью о теме, но я не совсем понимаю ее. Пожалуйста, дайте мне несколько советов, а также примеры при описании концепций.

Ответы [ 7 ]

127 голосов
/ 07 мая 2014

Java предоставляет два различных типа / класса Ссылочные объекты : strong и слабо . Слабые эталонные объекты можно разделить на soft и phantom . Давайте идти по пунктам.

Сильный эталонный объект

StringBuilder builder = new StringBuilder();

Это тип / класс ссылочного объекта по умолчанию, если не указано иное: builder является сильным ссылочным объектом. Этот вид ссылки делает указанный объект непригодным для GC. То есть всякий раз, когда на объект ссылается цепочка сильных ссылочных объектов , он не может быть подвергнут сборке мусора.

Слабый эталонный объект

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

Слабые ссылочные объекты не являются типом / классом ссылочных объектов по умолчанию, и для использования они должны быть явно указаны, как в примере выше. Этот вид ссылки делает эталонный объект пригодным для GC. То есть, если единственная ссылка, доступная для объекта StringBuilder в памяти, на самом деле является слабой ссылкой, то GC разрешается собирать мусор для объекта StringBuilder. Когда объект в памяти доступен только слабым эталонным объектам, он автоматически становится доступным для GC.

Уровни слабости

Могут быть зачислены два различных уровня слабости: мягкий и фантом .

A soft Контрольный объект в основном является слабым контрольным объектом, который остается в памяти немного больше: обычно он сопротивляется циклу GC до тех пор, пока не станет доступной память, и нет риска OutOfMemoryError (в этом случае , это может быть удалено).

С другой стороны, фантомный эталонный объект полезен только для точного определения момента, когда объект был эффективно удален из памяти: обычно они используются для исправления странного finalize () оживления / воскрешения поведение , поскольку они на самом деле не возвращают сам объект, а только помогают отслеживать их присутствие в памяти .

Слабые эталонные объекты идеально подходят для реализации модулей кеша. Фактически, своего рода автоматическое вытеснение может быть реализовано, позволяя ГХ очищать области памяти всякий раз, когда объекты / значения больше не достижимы цепочкой сильных ссылок. Примером является WeakHashMap , сохраняющий слабые ключи.

72 голосов
/ 10 мая 2012

Слабая ссылка:

Слабая ссылка, проще говоря, является ссылкой, которая недостаточно сильна, чтобы заставить объект оставаться в памяти. Слабые ссылки позволяют вам использовать способность сборщика мусора определять доступность для вас, поэтому вам не придется делать это самостоятельно.

Soft Reference:

Мягкая ссылка в точности похожа на слабую, за исключением того, что она меньше стремится выбросить объект, на который она ссылается. Объект, который является только слабо достижимым (самые сильные ссылки на него - WeakReferences), будет отброшен в следующем цикле сборки мусора, но объект, который легко доступен, обычно остается на некоторое время.

Фантомная ссылка:

Фантомная ссылка совершенно отличается от SoftReference или WeakReference. Его захват его объекта настолько слаб, что вы даже не можете получить объект - его метод get () всегда возвращает ноль. Единственное использование для такой ссылки - отслеживание того, когда она помещается в ReferenceQueue, поскольку в этот момент вы знаете, что объект, на который она указала, мертв.

Этот текст был извлечен из: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references

23 голосов
/ 08 апреля 2012

Простая разница между SoftReference и WeakReference обеспечивается Android Developer .

Разница между SoftReference и WeakReference - это момент времени, когда принимается решение очистить и поставить в очередь ссылку:

  • A SoftReference следует очистить и поставить в очередь как можно позже, то есть в случае, если виртуальной машине угрожает нехватка памяти.

  • A WeakReference может быть очищен и помещен в очередь, как только станет известно, что слабо ссылки.

16 голосов
/ 21 марта 2012

Три термина, которые вы использовали, в основном связаны с правом объекта на сбор мусора.

Слабая ссылка :: Это ссылка, которая недостаточно сильна, чтобы заставить объект оставаться в памяти. Его прихоти для сборщика мусора . Вы не можете заставить GC не забирать его .

Мягкая ссылка :: Это более или менее похоже на слабую ссылку. Но вы можете сказать, что он удерживает объект немного сильнее, чем слабая ссылка из сборки мусора.

Если сборщики мусора собирают слабые ссылки в самом первом жизненном цикле, они собирают мягкие ссылки в следующем цикле сбора мусора.

Сильная ссылка :: Это прямо противоположно двум вышеупомянутым ссылкам. Им меньше нравится собирать мусор (в основном они никогда не собираются).

Вы можете обратиться к следующей ссылке для получения дополнительной информации:

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html

10 голосов
/ 29 июля 2015

4 градуса отсчета - Strong, Weak, Soft, Phantom

Сильный - это вид отсчета, который делает указанный объект непригодным для GC.Занятия строителей.Например - StringBuilder

Слабый - это ссылка, которая подходит для GC.

Soft - это тип ссылки, объект которой подходит для GC, пока память не будет доступна.Лучше всего для кеша изображений.Он будет удерживать их до тех пор, пока память не станет доступной.

Фантом - это своего рода ссылка, объект которой непосредственно подходит для GC.Используется только для того, чтобы знать, когда объект удален из памяти.

использует:

  1. Позволяет идентифицировать, когда объект точно удаляется из памяти..

  2. Если метод finalize() перегружен, сборщик мусора может не произойти своевременно для объектов, подходящих для сборщика мусора двух классов.Так что фантомные ссылки дают им право на GC до finalize(), поэтому вы можете получить OutOfMemoryErrors , даже если большая часть кучи является мусором.

Слабыйссылки идеально подходят для реализации модулей кеша.

5 голосов
/ 15 декабря 2018

Эта статья может быть очень полезна для понимания сильных, мягких, слабых и фантомных ссылок.


Чтобы дать вам резюме,

Если у вас есть сильная ссылка на объект, тогда GC (сборщик мусора) никогда не сможет собрать / вернуть объект.

Если у вас есть только слабые ссылки на объект(без сильных ссылок), тогда объект будет возвращен GC в следующем цикле GC.

Если у вас есть только мягкие ссылки на объект (без сильных ссылок),тогда объект будет возвращен GC только тогда, когда JVM не хватит памяти.

Мы создаем фантомных ссылок на объект, чтобы отслеживать, когда объект помещается в очередь в ReferenceQueue.Как только вы узнаете, что можете выполнить детальную финализацию.(Это избавит вас от случайного воскрешения объекта, так как фантомные ссылки не дают вам рефератов).Я бы посоветовал вам прочитать эту статью, чтобы получить более подробную информацию об этом.


Итак, вы можете сказать, что сильные ссылки имеют предельную силу (никогда не может быть собран GC)

Мягкие ссылки мощнее , чем слабые ссылки (поскольку они могут выйти из цикла GC, пока JVM не исчерпает память)

Слабые ссылки даже менее мощный , чем мягкие ссылки (так как они не могут спровоцировать какой-либо цикл GC и будут возвращены, если у объекта нет другой сильной ссылки).


Аналогия ресторана

  • Официант - GC
  • Вы - Объект в куче
  • Площадь / пространство ресторана - Пространство кучи
  • Новый клиент - Новый объект, для которого требуется таблицаресторан

Теперь, если вы являетесь сильным клиентом (аналог сильной рекомендации), то даже если в ресторан придет новый клиент или что-либо еще, что вас порадует, вы никогда не уйдетеВаш стол (область памяти на куче).Официант не имеет права просить вас (или даже просить вас) покинуть ресторан.

Если вы являетесь мягким клиентом (аналог мягкого обращения), то если придет новый клиентв ресторане официант не попросит вас покинуть стол, если не останется другого пустого стола для размещения нового клиента.(Другими словами, официант попросит вас покинуть стол только в том случае, если заходит новый клиент, и для этого нового клиента не осталось другой таблицы)

Если вы слабый клиент (аналог слабой ссылки), затем официант по своему желанию может (в любой момент) попросить вас покинуть ресторан: P

5 голосов
/ 20 марта 2018

Сильные ссылки

Это ваши обычные ссылки на объекты, которые мы кодируем ежедневно:

Employee emp = new Employee();

Переменная «emp» содержит строгую ссылку на объект Employee и объекты, которые доступны черезлюбая цепочка сильных ссылок не подходит для сбора мусора.Обычно это то, что вы хотите, но не всегда.Теперь предположим, что мы выбираем большое количество сотрудников из базы данных в коллекции или на карте, и нам нужно регулярно обрабатывать их, поэтому, чтобы сохранить производительность, мы будем держать их в кэше.

Что касаетсяэто хорошо, но теперь нам нужны разные данные, и нам не нужны эти объекты Employee, и на них нет ссылок нигде, кроме кеша.Что вызывает утечку памяти, потому что эти объекты не используются, но все еще не подходят для сборки мусора, и мы не можем удалить эти объекты из кэша, потому что у нас нет ссылки на них?Так что здесь либо нам нужно очистить весь кэш вручную, что утомительно, либо мы могли бы использовать ссылки другого типа, например, Weak References.

Weak References

Слабая ссылка не закрепляет объект в памяти ибудет GC'd в следующем цикле GC, если нет ссылок из других ссылок.Мы можем использовать класс WeakReference, предоставляемый Java, для создания кэшей указанного выше типа, которые не будут хранить объекты, на которые нет ссылок откуда-либо еще.

WeakReference<Cache> cache = new WeakReference<Cache>(data);

Для доступа к данным вам необходимо вызвать cache.get ().Этот вызов get может вернуть null, если слабая ссылка была собрана сборщиком мусора: необходимо проверить возвращаемое значение, чтобы избежать NPE.Java предоставляет коллекции, которые используют слабые ссылки, например, класс WeakHashMap хранит ключи (не значения) в качестве слабых ссылок.Если ключ имеет значение GC, значение также будет автоматически удалено с карты.

Поскольку слабые ссылки также являются объектами, нам необходим способ их очистки (они больше не нужны, когда объект онибыли ссылки были GC'd).Если вы передадите ReferenceQueue в конструктор для слабой ссылки, сборщик мусора добавит эту слабую ссылку к ReferenceQueue до того, как они будут завершены или GC'd.Вы можете периодически обрабатывать эту очередь и обрабатывать мертвые ссылки.

Мягкие ссылки

Мягкая ссылка похожа на слабую ссылку, но она с меньшей вероятностью будет собирать мусор.Мягкие ссылки очищаются по усмотрению сборщика мусора в ответ на запрос памяти.Виртуальная машина гарантирует, что все мягкие ссылки на мягко достижимые объекты будут очищены до того, как она выдаст OutOfMemoryError.

Фантомные ссылки

Фантомные ссылки являются самым слабым из всех ссылочных типов, вызывая getна них всегда будет возвращаться ноль.На объект ссылаются фантомно после того, как он был завершен, но до того, как его выделенная память была освобождена, в отличие от слабых ссылок, которые ставятся в очередь до того, как они завершены, или ссылки фантома GC'd редко используются.

Итакчем они полезны?Когда вы создаете фантомную ссылку, вы всегда должны передавать ReferenceQueue.Это означает, что вы можете использовать фантомную ссылку, чтобы увидеть, когда ваш объект GC'd.

Эй, так что, если слабые ссылки ставятся в очередь, когда они считаются финализированными, но еще не GC'd, мы могли бы создать новыйсильная ссылка на объект в блоке финализатора и предотвращение объекта GC'd.Да, вы можете, но вы, вероятно, не должны этого делать.Для проверки этого случая цикл GC будет происходить как минимум дважды для каждого объекта, если только этот объект не доступен только по фантомной ссылке.Вот почему вы можете исчерпать кучу, даже если ваша память содержит много мусора.Фантомные ссылки могут предотвратить это.

Вы можете прочитать больше в моей статье Типы ссылок в Java (Сильные, Мягкие, Слабые, Фантомные) .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...