Я прочитал эту статью на эту тему, но я не совсем понимаю. Пожалуйста, дайте мне несколько советов вместе с примерами при описании концепций.
Я прочитал эту статью на эту тему, но я не совсем понимаю. Пожалуйста, дайте мне несколько советов вместе с примерами при описании концепций.
Ответы:
Java предоставляет два разных типа / класса ссылочных объектов : сильный и слабый . Слабые эталонные объекты можно далее разделить на мягкие и фантомные .
Давайте идти по пунктам.
Сильный Ссылочный Объект
StringBuilder builder = new StringBuilder();
Это тип / класс ссылочного объекта по умолчанию, если не указано иное: builder
это сильный ссылочный объект. Этот вид ссылки делает указанный объект непригодным для GC. То есть всякий раз, когда на объект ссылается цепочка сильных ссылочных объектов , он не может быть подвергнут сборке мусора.
Слабый эталонный объект
WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);
Слабые ссылочные объекты не являются типом / классом ссылочных объектов по умолчанию, и для их использования они должны быть явно указаны, как в примере выше. Этот вид ссылки делает эталонный объект пригодным для GC. То есть, если единственная ссылка, достижимая для StringBuilder
объекта в памяти, на самом деле является слабой ссылкой, то GC разрешается собирать мусорStringBuilder
объект . Когда объект в памяти доступен только слабым ссылочным объектам, он автоматически получает право на сборку мусора.
Уровни слабости
Два различных уровня слабости могут быть зачислены: мягкий и призрачный .
Мягкий Reference Object в основном слабая ссылка на объект , который остается в памяти немного больше: обычно, он сопротивляется GC цикла до тех пор память не доступна , и есть риск OutOfMemoryError
(в этом случае, он может быть удален).
С другой стороны, фантомный эталонный объект полезен только для того, чтобы точно знать, когда объект был эффективно удален из памяти: обычно они используются для исправления странного поведения возрождения / воскрешения finalize () , поскольку они фактически не возвращают сам объект, но только помощь в отслеживании их памяти присутствия .
Слабые ссылочные объекты идеально подходят для реализации модулей кеша. Фактически, своего рода автоматическое выселение может быть реализовано, позволяя ГХ очищать области памяти всякий раз, когда объекты / значения больше не достижимы цепочкой сильных ссылок. Примером является WeakHashMap, сохраняющий слабые ключи.
Слабая ссылка:
Проще говоря, слабая ссылка - это ссылка, которая недостаточно сильна, чтобы заставить объект оставаться в памяти. Слабые ссылки позволяют вам использовать способность сборщика мусора определять доступность для вас, поэтому вам не придется делать это самостоятельно.
Мягкая ссылка:
Мягкая ссылка точно так же, как слабая ссылка, за исключением того, что она меньше стремится выбросить объект, на который она ссылается. Объект, который является только слабо достижимым (самые сильные ссылки на него - WeakReferences), будет отброшен в следующем цикле сборки мусора, но объект, который является легко достижимым, обычно остается на некоторое время.
Призрак Ссылка:
Фантомная ссылка сильно отличается от SoftReference или WeakReference. Его захват его объекта настолько слаб, что вы даже не можете получить объект - его метод get () всегда возвращает ноль. Единственное использование для такой ссылки - отслеживание того, когда она помещается в ReferenceQueue, так как в этот момент вы знаете, что объект, на который она указала, мертв.
Этот текст был извлечен из: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Простая разница между SoftReference
и WeakReference
обеспечивается Android Developer .
Разница между a SoftReference
и a WeakReference
- это момент времени, когда принимается решение очистить и поставить в очередь ссылку:
A SoftReference
следует очищать и ставить в очередь как можно позже, то есть в случае, если виртуальной машине угрожает нехватка памяти.
A WeakReference
может быть очищен и помещен в очередь, как только известно, что на него слабо ссылаются.
Три термина, которые вы использовали, в основном связаны с правом объекта на сбор мусора.
Слабая ссылка :: Это ссылка, которая недостаточно сильна, чтобы заставить объект оставаться в памяти. Это прихоть сборщика мусора для сбора этого объекта для сбора мусора. Вы не можете заставить этот GC не собирать его .
Мягкая ссылка :: Это более или менее похоже на слабую ссылку. Но вы можете сказать, что он удерживает объект немного сильнее, чем слабая ссылка из сборки мусора.
Если сборщики мусора собирают слабые ссылки в самом первом жизненном цикле, они собирают мягкие ссылки в следующем цикле сбора мусора.
Сильная ссылка :: Это прямо противоположно двум вышеупомянутым ссылкам. Они меньше любят собирать мусор (в основном они никогда не собираются).
Вы можете обратиться к следующей ссылке для получения дополнительной информации:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Эта статья может быть очень полезна для понимания сильных, мягких, слабых и фантомных ссылок.
Чтобы дать вам резюме,
Если у вас есть сильная ссылка на объект, то этот объект никогда не может быть собран / утилизирован GC (сборщик мусора).
Если у вас есть только слабые ссылки на объект (без сильных ссылок), то объект будет восстановлен GC в самом следующем цикле GC.
Если у вас есть только мягкие ссылки на объект (без сильных ссылок), то объект будет восстановлен GC только тогда, когда JVM не хватит памяти.
Мы создаем фантомные ссылки на объект, чтобы отслеживать, когда объект помещается в очередь в ReferenceQueue
. Как только вы узнаете, что можете выполнить детальную финализацию. (Это избавит вас от случайного воскрешения объекта, так как фантомные ссылки не дают вам рефератов). Я бы посоветовал вам прочитать эту статью, чтобы получить более подробную информацию об этом.
Таким образом, вы можете сказать, что сильные ссылки имеют максимальную силу (никогда не могут быть собраны GC)
Мягкие ссылки более эффективны, чем слабые (поскольку они могут избежать цикла GC, пока JVM не исчерпает память)
Слабые ссылки даже менее мощны, чем мягкие ссылки (поскольку они не могут избежать любого цикла GC и будут возвращены, если у объекта нет другой сильной ссылки).
Ресторанная аналогия
Теперь, если вы сильный клиент (аналог сильной рекомендации), то даже если в ресторан приходит новый клиент или что-то такое, что всегда радует, вы никогда не покинете свой стол (область памяти в куче). Официант не имеет права говорить вам (или даже просить вас) покинуть ресторан.
Если вы мягкий клиент (аналог мягкого отзыва), то, если в ресторан приходит новый клиент, официант не будет просить вас покинуть стол, если не осталось другой пустой таблицы для размещения нового клиента. (Другими словами, официант попросит вас покинуть стол только в том случае, если заходит новый клиент, и для этого нового клиента не осталось другой таблицы)
Если вы слабый клиент (аналог слабой ссылки), тогда официант по своему желанию может (в любой момент) попросить вас покинуть ресторан: P
4 степени референции - Strong, Weak, Soft, Phantom
Сильный - это своего рода ссылка, которая делает указанный объект непригодным для GC. Занятия строителей. например - StringBuilder
Слабый - это ссылка, которая имеет право на GC.
Soft - это своего рода ссылка, объект которой подходит для GC, пока память не станет доступной. Лучше всего для кеша изображений. Он будет держать их до тех пор, пока память не станет доступной.
Фантом - это своего рода ссылка, объект которой имеет прямое право на получение GC. Используется только для того, чтобы узнать, когда объект удален из памяти.
использование:
Позволяет определить, когда объект точно удаляется из памяти.
если
finalize()
метод перегружен, то GC может не произойти своевременно для подходящих объектов GC двух классов. Так что фантомные ссылки делают их подходящими для GC раньшеfinalize()
, поэтому вы можете получить OutOfMemoryErrors, даже если большая часть кучи является мусором.
Слабые ссылки идеально подходят для реализации модулей кеша.
Это ваши обычные ссылки на объекты, которые мы кодируем ежедневно:
Employee emp = new Employee();
Переменная «emp» содержит строгую ссылку на объект Employee, а объекты, доступные через любую цепочку строгих ссылок, не подходят для сборки мусора. Обычно это то, что вы хотите, но не всегда. Теперь предположим, что мы извлекаем много сотрудников из базы данных в коллекции или на карте, и нам нужно регулярно обрабатывать их, поэтому для поддержания производительности мы будем держать их в кэше.
Насколько это хорошо, но теперь нам нужны разные данные, и нам не нужны эти объекты Employee, и на них нет ссылок нигде, кроме кеша. Что вызывает утечку памяти, потому что эти объекты не используются, но все еще не подходят для сборки мусора, и мы не можем удалить эти объекты из кэша, потому что у нас нет ссылки на них? Так что здесь либо нам нужно очистить весь кеш вручную, что утомительно, либо мы могли бы использовать ссылки другого типа, например, Weak References.
Слабая ссылка не закрепляет объект в памяти, и в следующем цикле GC она будет GC, если на нее не ссылаются другие ссылки. Мы можем использовать класс WeakReference, предоставляемый Java, для создания кэшей вышеуказанного типа, которые не будут хранить объекты, на которые нет ссылок откуда-либо еще.
WeakReference<Cache> cache = new WeakReference<Cache>(data);
Для доступа к данным вам нужно вызвать cache.get (). Этот вызов get может вернуть null, если слабая ссылка была собрана сборщиком мусора: вы должны проверить возвращаемое значение, чтобы избежать NPE. Java предоставляет коллекции, которые используют слабые ссылки, например, класс WeakHashMap хранит ключи (не значения) как слабые ссылки. Если ключ GC'd, то значение будет автоматически удалено и с карты.
Поскольку слабые ссылки тоже являются объектами, нам нужен способ их очистки (они больше не нужны, когда объект, на который они ссылались, был GC'd). Если вы передадите ReferenceQueue в конструктор для слабой ссылки, сборщик мусора добавит эту слабую ссылку в ReferenceQueue до того, как они будут завершены или GC'd. Вы можете периодически обрабатывать эту очередь и обрабатывать мертвые ссылки.
SoftReference похож на WeakReference, но он с меньшей вероятностью будет собирать мусор. Мягкие ссылки очищаются по усмотрению сборщика мусора в ответ на запрос памяти. Виртуальная машина гарантирует, что все мягкие ссылки на мягко достижимые объекты будут очищены до того, как она выдаст OutOfMemoryError.
Фантомные ссылки - самый слабый из всех ссылочных типов, вызов get для них всегда будет возвращать ноль. На объект ссылаются фантомно после того, как он был завершен, но до того, как его выделенная память была освобождена, в отличие от слабых ссылок, которые ставятся в очередь до того, как они завершены, или ссылки фантома GC'd редко используются.
Так чем они полезны? Когда вы создаете фантомную ссылку, вы всегда должны передавать ReferenceQueue. Это означает, что вы можете использовать фантомную ссылку, чтобы увидеть, когда ваш объект GC'd.
Эй, так что, если слабые ссылки ставятся в очередь, когда они считаются финализированными, но еще не GC'd, мы можем создать новую сильную ссылку на объект в блоке финализатора и предотвратить объект GC'd. Да, вы можете, но вы, вероятно, не должны этого делать. Для проверки этого случая цикл GC будет происходить как минимум дважды для каждого объекта, если этот объект не доступен только по фантомной ссылке. Вот почему вы можете исчерпать кучу, даже если ваша память содержит много мусора. Призрачные ссылки могут предотвратить это.
Вы можете прочитать больше в моей статье Типы ссылок в Java (Strong, Soft, Weak, Phantom) .