Подтвердить что ты не робот

Java: разница между сильным/мягким/слабым/phantom ссылкой

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

4b9b3361

Ответ 1

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

Сильный Ссылочный Объект

StringBuilder builder = new StringBuilder();

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

Мягкая ссылка:

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

Phantom Ссылка:

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

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

Ответ 3

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

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

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

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

Ответ 4

Три условия, которые вы использовали, в основном связаны с возможностью Object для получения Мусора.

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

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

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

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

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

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

Ответ 5

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

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

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

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

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

использует:

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

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

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

Ответ 6

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

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

Employee emp = new Employee();

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

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

Слабые ссылки

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

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

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

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

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

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

Призрачные Ссылки

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

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

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

Вы можете прочитать больше в моей статье Типы ссылок в Java (Strong, Soft, Weak, Phantom).

Ответ 7

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


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

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

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

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

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


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

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

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


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

  • Официант - GC
  • Вы - Объект в куче
  • Зона ресторана/пространство - куча места
  • Новый клиент - новый объект, который хочет столик в ресторане

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

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

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