Лучшее время для отбора WeakReferences из коллекции в .NET - PullRequest
3 голосов
/ 23 апреля 2011

У меня есть коллекция (я пишу Слабый словарь ), и мне нужно периодически отбирать мертвые WeakReferences. Обычно я видел проверки в методах Add и Remove, которые говорят: «После X изменений в коллекции, пришло время отбраковать». Это будет приемлемо для меня, но, похоже, должен быть лучший способ.

Мне бы очень хотелось знать, когда GC запускается и запускает мой код очистки сразу после. В конце концов, GC, вероятно, является лучшим механизмом для определения того, когда подходящее время для очистки мертвых ссылок. Я нашел Уведомления о сборке мусора , но это не похоже на то, что я хочу. Я не хочу создавать отдельную ветку только для мониторинга GC. В идеале моя коллекция должна реализовывать IWantToRunCodeDuringGC или подписаться на событие System.GC.Collected. Но .NET Framework, вероятно, не может доверять пользовательскому коду, выполняемому во время GC ...

Или, может быть, есть другой подход, который я пропускаю.

РЕДАКТИРОВАТЬ: Я не думаю, что это имеет значение, если мой код выполняется после, до или во время GC.

Ответы [ 3 ]

2 голосов
/ 23 апреля 2011

Полагаю, вы хотите создать слабый словарь как способ «ленивого» кеширования некоторых данных.

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

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

1 голос
/ 23 апреля 2011

Разве вы не можете просто использовать объект без ссылок, а затем вызвать некоторый код в финализаторе?Финализатор вызывается, когда ГХ собирает объект.

РЕДАКТИРОВАТЬ: Тогда, конечно, вы не будете знать, когда ГХ было сделано .. Хм.

0 голосов
/ 12 декабря 2011

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

...