5

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

ответ

0

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

Вот аналогичный вопрос к твоему:

Why doesn't .NET have a SoftReference as well as a WeakReference, like Java?

+3

-1 Тони сказал, что хочет реализовать кеш памяти. Тем не менее MSDN говорит об этом в WeakReferences: «Избегайте использования слабых ссылок в качестве автоматического решения проблем управления памятью. Вместо этого создайте эффективную политику кэширования для обработки объектов вашего приложения». –

2

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

Here's an article, который показывает, как использовать класс кэширования в Windows Forms приложение.

2

Кэш 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; 
    } 
} 

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

1

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

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

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