Эквивалентно SoftReference в .net?

Я знаком с WeakReference, но я ищу ссылочный тип, который очищается только тогда, когда память низкая, а не просто каждый раз, когда выполняется gc (как Java SoftReference). Я ищу способ реализовать чувствительный к памяти кеш.

5 ответов

Нет, нет эквивалента. Есть ли особая причина, по которой WeakReference не будет выполнять эту работу?

Вот аналогичный вопрос для вас:

Почему .NET не имеет SoftReference, а также WeakReference, например Java?


Кэш ASP.NET дает вам поведение, зависящее от памяти, с недостатком, что все требует уникального ключа. Тем не менее, вы должны иметь возможность удерживать WeakReference для объекта, который вы разместили в кеше ASP.NET. Сильная ссылка на кеш будет держать GC в состоянии ожидания до тех пор, пока кэш не решит, что его нужно удалить в свободную память. Функция WeakReference предоставляет вам доступ к объекту без выполнения поиска с помощью ключа кеша.

Foo cachedData = new Foo();
WeakReference weakRef = new WeakReference( cachedData );
HttpRuntime.Cache[Guid.NewGuid().ToString()] = cachedData;
...
if ( weakRef.IsAlive )
{
 Foo strongRef = weakRef.Target as Foo;
}

Вы можете создать класс SoftReference, расширив WeakReference вдоль строк

class SoftReference : WeakReference
{
 public SoftReference( object target ) : base( target )
 {
 HttpRuntime.Cache[Guid.NewGuid().ToString()] = target; 
 }
}

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


В дополнение к кэшу ASP.NET существует блок кэширования приложений из группы шаблонов и практик Microsoft.

http://msdn.microsoft.com/en-us/library/cc309502.aspx


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

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


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

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

Кстати, если бы у меня были мои druthers,.net поддержал бы другую ссылку, которую я не видел ни на одной платформе: ссылка "интерес к кому-то еще", которая будет использоваться в сочетании с типом WeakReference. Ссылка "интерес к кому-то" может быть использована в качестве сильной ссылки, но подходящая конфигурация WeakReference будет признана недействительной, если только сильные ссылки на ее цель будут "интересны для кого-то другого". Такая концепция может повысить эффективность при использовании параллельного GC, в тех случаях, когда обработчик с слабым событием неоднократно генерирует сильную ссылку на свою цель. Если никто действительно не интересуется тем, что делает обработчик событий с его целью, было бы желательно, чтобы обработчик мог отказаться от подписки.

licensed under cc by-sa 3.0 with attribution.