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

Почему нам нужна слабая ссылка в java

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

  • Почему нам нужна слабая ссылка в java?
  • Каковы практические (некоторые) применения слабых ссылок в java? Если вы можете поделиться тем, как вы использовали в своем проекте, это будет здорово!
4b9b3361

Ответ 1

На самом деле довольно часто плохая идея использовать слабые хэшмапы. Для одного это легко ошибиться, но еще хуже он обычно используется для реализации своего рода кеша.

Это означает следующее: ваша программа работает нормально с хорошей производительностью в течение некоторого времени, при стрессе мы выделяем все больше и больше памяти (больше запросов = больше давления памяти =, вероятно, больше записей кэша), что затем приводит к GC.

Теперь, когда ваша система находится под большим стрессом, вы получаете не только GC, но и теряете весь свой кеш, только когда вам это нужно больше всего. Не устраивайте эту проблему, поэтому вам нужно хотя бы использовать жесткий LRU-кэш с ограниченным размером, чтобы уменьшить эту проблему - вы все равно можете использовать weakrefs, но только в качестве дополнительной помощи.

Я видел более одного проекта, попавшего в эту "ошибку".

Ответ 2

Наиболее "однозначно разумное" использование слабых ссылок, которые я видел, это Guava Striped, который блокирует чередование. В принципе, если ни одна из потоков в настоящее время не содержит ссылку на переменную блокировки, то нет причин держать эту блокировку вокруг, не так ли? Этот замок, возможно, использовался в прошлом, но теперь он не нужен.

Если бы мне пришлось указывать правило, когда вы используете это, я бы сказал, что мягкие ссылки предпочтительнее, если вы можете что-то использовать в будущем, но можете перепроверить его, если он вам действительно нужен; слабые ссылки особенно предпочтительны, когда вы можете быть уверены, что значение никогда не понадобится после того, как ссылка исчезнет из памяти. (Например, если вы используете стандартное ссылочное равенство для конкретной реализации equals(Object) для типа ключа карты, и объект перестает ссылаться куда-либо еще, вы можете быть уверены, что запись никогда не будет ссылаться снова.

Ответ 3

Основная причина для использования слабых ссылок - косвенно, через WeakHashMap.

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

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

Ответ 4

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

Ответ 5

Да, и это имеет хорошее влияние.

Пример проблемы "серийный номер виджета" выше, проще всего использовать встроенный класс WeakHashMap. WeakHashMap работает точно так же, как HashMap, за исключением того, что ключи (а не значения!) WeakHashMap на слабые ссылки. Если ключ WeakHashMap становится мусором, его запись удаляется автоматически. Это позволяет избежать ловушек, которые я описал, и не требует никаких изменений, кроме перехода от HashMap к WeakHashMap. Если вы придерживаетесь стандартного соглашения о ссылках на свои карты через интерфейс Map, никакой другой код даже не должен знать об этом изменении.

Ссылка

Ответ 6

Слабые реквизиты Объекты необходимы для платформы JVM, чтобы обеспечить средства против утечек памяти.

Как Java-разработчики должны знать, Java может протекать, больше, чем ожидалось. Это утверждение particurarly верно в тех случаях, когда объект больше не используются, но некоторые коллекции до сих пор сильно refence этого экземпляра: очень простой, но рецидивирующий пример утечки памяти, в том, что область памяти не будет освобождаться, пока сильная ссылка не существует.

В приведенном выше случае слабый ссылочный объект в коллекции гарантирует, что: без сильной цепи ссылок, но с только слабыми цепями, экземпляр может быть отфильтрован как собираемый предмет одежды.

На мой взгляд, все функции, предоставляемые платформой Java, в какой-то мере полезны: очень опытный программист может быстро и надежно управлять Java, поскольку С++ пишет очень качественный код.

Ответ 8

Отделение от паба-суб или событийного автобуса

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

В таких сценариях, как публикация-подписка или шина событий, хранится коллекция ссылок на объекты подписки. Эти ссылки должны быть слабыми, чтобы подписчик мог легко выйти за рамки, не потрудившись отписаться. Подписчик может просто "исчезнуть" после того, как все другие места в приложении выпустили свою сильную ссылку. На этом этапе нет необходимости, чтобы список подписки или шина событий продолжали держаться за подписчика. Использование WeakReference позволяет объекту продолжать свой путь в забвение.

Подписывающийся объект может быть подписан без его ведома, передан в pub-sub или на шину событий каким-либо другим сторонним объектом. Координация вызова для отказа от подписки позднее в жизненном цикле абонента может быть довольно громоздкой. Таким образом, позволить абоненту исчезнуть без формальной отмены подписки может значительно упростить ваш код и избежать трудных ошибок в случае сбоя при координации отписки.

Вот пример поточно-ориентированного набора слабых ссылок, как видно из этого ответа и этого ответа.

    this.subscribersSet =
            Collections.synchronizedSet(
                    Collections.newSetFromMap(
                            new WeakHashMap <>()
                    )
            );

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