2015-08-08 2 views
6

System.Runtime.Caching.MemoryCache - это класс в .NET Framework (версия 4+), который кэширует объекты в памяти, используя строки как ключи. Более System.Collections.Generic.Dictionary<string, object>, этот класс имеет все виды колоколов и свистов, которые позволяют вам настроить, насколько большой кеш может вырасти до (в абсолютном или относительном выражении), установить разные политики истечения срока действия для разных элементов кэша и многое другое.Что означают ограничения памяти MemoryCache?

Мои вопросы касаются пределов памяти. Ни один из документов на MSDN, по-видимому, не объясняет это удовлетворительно, а код в Reference Source довольно непрозрачен. Извините, что все это свалило в один «вопрос», но я не могу понять, как взять некоторые из них в свои собственные вопросы, потому что они действительно просто разные взгляды на один общий вопрос: «Как вы примирите идиоматический C#/.NET с понятием общего полезного кеша в памяти, который имеет настраиваемые пределы памяти, которые практически полностью реализованы в управляемом коде? "

  1. Учитываются ли размеры ключей в пространстве, которое считается MemoryCache? Как насчет ключей в станем пуле, каждый из которых должен только добавить размер ссылки на объект к размеру кеша?
  2. Учитывает ли MemoryCache больше, чем размер ссылок на объекты, которые он хранит при определении размера объекта, хранящегося в пуле? Я имею в виду ... он должен, не так ли? В противном случае параметры конфигурации крайне вводят в заблуждение для обычного случая ... для остальных вопросов я предполагаю, что это так.
  3. Учитывая, что MemoryCache почти наверняка считает больше, чем размер ссылок на объекты значений, хранящихся в кеше, насколько он глубоко уходит?
    1. Если я реализовывал что-то вроде этого, я нашел бы очень трудно рассмотреть использование памяти «дети» члены отдельных объектов, не также вытягивать в «родительских» эталонных свойствах.
    2. например, представьте себе класс в игровом приложении, Player. Player имеет какое-то определенное для игрока состояние, которое инкапсулировано в свойство public PlayerStateData PlayerState { get; }, которое инкапсулирует, в каком направлении находится игрок, сколько звездочек они держат и т. Д., А также ссылку на состояние всей игры public GameStateData GameState { get; }, которые могут быть использованы для получения обратно в состояние игры (намного больше) из метода, который знает только об игроке.
    3. Учитывает ли MemoryCache как PlayerState, так и GameState при рассмотрении размера вклада в кеш?
    4. Возможно, это больше похоже на «что такое всего размер на управляемой куче, занятой объектами, непосредственно хранящимися в кеше, и все, что доступно через члены этих объектов»?
    5. Кажется, было бы глупо умножать размер вклада GameState на лимит на 5 только потому, что 5 игроков кэшированы ... но опять же, вероятная реализация может сделать именно это, и это сложно подсчитать PlayerState без учета GameState.
  4. Если объект хранится несколько раз в MemoryCache, каждая запись подсчитывается отдельно до предела?
  5. Связано с предыдущим, если объект хранится непосредственно в MemoryCache, но также косвенно через членов другого объекта, какое влияние оказывает либо на ограничение памяти?
  6. Если объект хранится в MemoryCache, но также ссылается на некоторые другие живые объекты, полностью отключенные от MemoryCache, какие объекты подсчитываются против предела памяти? А если это массив объектов, некоторые (но не все) из которых имеют входящие внешние ссылки?

Мои собственные исследования привели меня к SRef.cs, который я дал на попытке понять после получения here, который впоследствии приводит here. Угадав ответы на все эти вопросы, он будет вращаться вокруг поиска и медитации на коде, который, в конечном счете, заполняет INT64, который хранится в этом дескрипторе.

+0

IMO самая полезная реализация обработки предельных значений MemoryCache предполагает, что кэш может отлично ответить на вопрос: «Если бы я был очищен и после этого был запущен полный GC, то сколько байтов памяти было бы освобождено во время этого запуска GC ?» Но чем больше я думаю об этом, тем больше ожидаю, что его ответ будет сильно раздутым, если владелец кеша не соблюдает определенный набор нераскрытых (или, по крайней мере, неоткрытых) правил, поэтому это имеет значение не только для теоретические причины. –

+0

Я пришел сюда, задавая точно такие же вопросы, особенно в отношении ссылок на общее состояние. Другой вопрос также преследует меня ... если ваш кеш-объект (граф) растет или сжимается после того, как он был помещен в кеш ...? Все это довольно расплывчато. – spender

ответ

1

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

MemoryCache использует специальную ссылку «размер» для измерения размера объектов. Все это выглядит как гигантский взломать исходный код кэша памяти, включающий отражение, чтобы обернуть внутренний тип, называемый «System.SizedReference», который из того, что я могу сказать, заставляет GC установить размер графического объекта, на который он указывает во время gen 2 коллекции.

Из моего тестирования этот WILL включает размер родительских объектов и, следовательно, все дочерние объекты, на которые ссылается родительский элемент и т. Д., Но я обнаружил, что если вы делаете ссылки на родительские объекты на слабые ссылки (то есть через WeakReference или WeakReference<>) то он больше не считается частью графического объекта, так что это то, что я делаю для всех объектов кеша сейчас.

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

Если вы хотите поиграть с ним самостоятельно, просто скопируйте код с SRef.cs, создайте граф объектов и укажите для него новый экземпляр SRef, а затем вызовите GC.Collect. После коллекции приблизительный размер будет установлен на размер графа объекта.