Итак, я размышлял над некоторыми идеями управления памятью в последнее время - в частности, я смотрел на реализацию менеджера памяти на основе подсчета ссылок. Конечно, всем известно, что циркулярные ссылки убивают наивный подсчет ссылок. Решение: слабые ссылки. Лично я ненавижу использовать слабые ссылки таким образом (есть другие более интуитивные способы борьбы с этим, через обнаружение циклов), но это заставило меня задуматься: где еще может быть полезно использовать слабую ссылку?
Я полагаю, что существует какая-то причина, по которой они существуют, особенно на языках с трассировкой коллекции мусора, которые не страдают от циклической ссылки (С# и Java - это те, с которыми я знаком, и Java даже имеет три вида слабых ссылок!). Однако, когда я пытался найти для них какие-то надежные прецеденты, у меня в значительной степени были такие идеи, как "Использовать их для реализации кешей" (я видел это несколько раз на SO). Мне это тоже не нравится, поскольку они полагаются на то, что GC трассировки, скорее всего, не будет собирать объект сразу же после того, как он больше не будет сильно ссылаться, за исключением ситуаций с низкой памятью. Эти типы случаев абсолютно недействительны со ссылкой на GC, поскольку объект уничтожается сразу же после того, как он больше не ссылается (за исключением, возможно, в случае циклов).
Но это действительно заставляет меня задаться вопросом: как может быть полезно использовать слабую ссылку? Если вы не можете рассчитывать на это, ссылаясь на объект, и его не нужно для таких вещей, как разбиение циклов, то зачем использовать его?