Почему .NET не имеет SoftReference, а также WeakReference, как Java? - PullRequest
17 голосов
/ 27 ноября 2008

Я действительно люблю WeakReference's. Но я хотел бы, чтобы был способ сообщить CLR, насколько (скажем, по шкале от 1 до 5), насколько слабым вы считаете ссылку. Это было бы замечательно.

У Java есть SoftReference, WeakReference, и я считаю, что также существует третий тип, называемый «фантомной ссылкой». Это 3 уровня, в которых GC имеет другой алгоритм поведения при принятии решения, получает ли этот объект отбивную.

Я подумываю о создании подкласса WeakReference .NET (к счастью и немного странного, он не запечатан), чтобы создать псевдо-SoftReference, основанный на таймере истечения или что-то в этом роде.

Ответы [ 9 ]

19 голосов
/ 18 августа 2011

Я считаю, что фундаментальная причина того, что NET не имеет мягких ссылок, заключается в том, что она может полагаться на операционную систему с виртуальной памятью. Процесс Java должен указать свою максимальную память ОС (например, с -Xmx128M), и он никогда не занимает больше памяти ОС, чем эта. Принимая во внимание, что процесс NET продолжает забирать нужную ему память ОС, которую ОС снабжает виртуальной памятью на диске, когда заканчивается ОЗУ. Если NET разрешает мягкие ссылки, то среда выполнения NET не будет знать, когда их выпускать, если она либо не заглянет глубоко в ОС, чтобы увидеть, действительно ли ее память выгружена на диск (неприятная зависимость OS / CLR), либо не запросила среду выполнения укажите максимальный объем памяти процесса (например, эквивалент -Xmx). Я предполагаю, что Microsoft не хочет добавлять -Xmx в NET, потому что они думают, что ОС должна решать, сколько ОЗУ получает каждый процесс (выбирая, какие страницы виртуальной памяти хранить в ОЗУ или на диске), а не сам процесс.

12 голосов
/ 15 сентября 2012

Java SoftReferences используются при создании чувствительных к памяти кешей (они не служат никакой другой цели).

Начиная с .NET 4, .NET имеет класс System.Runtime.Caching.MemoryCache , который, вероятно, удовлетворит любые такие потребности.

4 голосов
/ 28 ноября 2008

Наличие слабой ссылки с различными уровнями слабости (приоритет) звучит приятно, но также может усложнить работу GC, а не облегчить ее. (Я понятия не имею о внутренностях GC, но) я бы предположил, что есть какая-то дополнительная статистика доступа, которая хранится для объектов WeakReference, чтобы GC мог эффективно их очистить (например, он мог бы избавиться от наименее используемых элементов первый).

Скорее всего, добавленная сложность не сделает ничего более эффективным, потому что самый эффективный способ - это сначала избавиться от редко используемых WeakReferences. Если бы вы могли назначить приоритет, как бы вы это сделали? Это пахнет преждевременной оптимизацией: программист не знает большую часть времени и догадывается; В результате получается более медленный цикл сбора GC, который, вероятно, восстанавливает неправильные объекты.

Однако возникает вопрос: если вы заботитесь о том, чтобы объект WeakReference.Target был возвращен, действительно ли это хорошее применение WeakReference?

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

4 голосов
/ 27 ноября 2008

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

3 голосов
/ 18 февраля 2010

Может быть, класс ASP.NET Cache (System.Web.Caching.Cache) может помочь достичь того, что вы хотите? Он автоматически удаляет объекты, если памяти становится мало:

Вот статья, в которой показано, как использовать класс Cache в приложении для форм Windows.

цитата из: Эквивалент SoftReference в .net?

2 голосов
/ 19 января 2009

Не забывайте, что у вас также есть стандартные ссылки (те, которые вы используете ежедневно). Это дает вам еще один уровень.

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

Я предполагаю, что .Net-дизайнеры почувствовали, что разница смущает большинство людей, или что SoftReferences добавляют больше сложности, чем они на самом деле хотели, и поэтому решили их опустить.

В качестве примечания, AFAIK PhantomReferences в основном предназначены для внутреннего использования виртуальной машиной и не предназначены для фактического использования клиентом.

1 голос
/ 28 ноября 2008

Может быть, должно быть свойство, в котором вы можете указать, какое Поколение> = объект до его сбора. Так что, если вы укажете 1, то это самая слабая из возможных ссылок. Но если вы укажете 3, тогда потребуется пережить не менее 3 предыдущих коллекций, прежде чем их можно будет рассматривать для самой коллекции.

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

(PS: я ОП, только что зарегистрировался. PITA, что он не наследует вашу историю от "незарегистрированных" аккаунтов.)

0 голосов
/ 19 января 2009

Не знаю, почему .NET не имеет Softreferences. НО в Java Softreferences ИМХО злоупотребляют. Причина в том, что, по крайней мере, на сервере приложений вы хотели бы иметь возможность влиять на каждое приложение, как долго живет ваш Softreferenzen. В настоящее время это невозможно в Java.

0 голосов
/ 28 ноября 2008

Ищете опцию 'trackResurrection', переданную в конструктор?

Класс GC также предлагает некоторую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...