Эквивалент 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 Cache ( System.Web.Caching.Cache) может помочь достичь того, чего вы хотите? Он автоматически удаляет объекты, если памяти становится мало:

Вот статья, которая показывает, как использовать класс Cache в приложении Windows Forms.

В дополнение к ASP.NET Cache есть блок приложения Caching из группы Microsoft Patterns and Practices.

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

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

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

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

Другие вопросы по тегам