Какой-нибудь практический пример длинной слабой ссылки?

Есть ли у кого-нибудь примерный "длинный" слабый справочник (не короткий)?

Это только для внутреннего использования?

Ответы

Ответ 1

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

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

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

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

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

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

Первый случай можно обработать с помощью короткого WeakReference. Определение того, что применяется второе или третье, требует длинного WeakReference. Обратите внимание, что после того, как соединение было завершено для завершения, менеджер соединений не будет интересоваться попыткой его повторного использования, но тем не менее все же должен знать о его существовании.