Я использую новую MemoryCache в .Net 4 с максимальным пределом размера кэша в МБ (я тестировал его установленным от 10 до 200 МБ, в системах с объемом памяти от 1,75 до 8 ГБ). ). Я не устанавливаю никакого истечения времени для объектов, так как я использую кеш просто как высокопроизводительный диск, и пока есть место, я хочу его использовать. К моему удивлению, кеш отказывался выселять какие-либо объекты, до такой степени, что я получил бы SystemOutOfMemory
исключения .
Я запустил perfmon , подключил мое приложение к .Net CLR Memory\#Bytes In All Heaps
, .Net Memory Cache 4.0
и Process\Private Bytes
- действительно, потребление памяти вышло из-под контроля, и записи кэша не регистрировались .
Некоторые гуглили и стек переполнения , скачали и прикрепили CLRProfiler и wham : выселения повсюду! Память оставалась в разумных пределах, основываясь на установленном мною ограниченном объеме памяти. Запустил его снова в режиме отладки, никаких выселений. CLRProfiler снова, выселения.
Наконец-то я заметил, что профилировщик заставил приложение работать без одновременной сборки мусора (также см. Полезный ТАК вопрос одновременной сборки мусора ). Я выключил его в своем app.config и, конечно же, выселений!
Похоже, в лучшем случае просто не хватает документации, чтобы не сказать: это работает только с одновременной сборкой мусора - , хотя я представляю ее, поскольку она портирована из ASP.NET, они могут не пришлось беспокоиться о одновременной сборке мусора .
Так кто-нибудь еще видел это? Я хотел бы получить некоторые другие впечатления, и, возможно, более образованные идеи.
Обновление 1
Я воспроизвел проблему в одном методе: похоже, что кэш должен записываться параллельно, чтобы не происходило его вытеснение (в режиме одновременного сбора мусора). Если есть какой-то интерес, я выложу тестовый код в публичный репозиторий. Я определенно добираюсь до глубокого конца пула CLR / GC / MemoryCache, и я думаю, что забыл свои сообщения ...
Обновление 2
Я опубликовал тестовый код на CodePlex , чтобы воспроизвести проблему. Также, возможно, представляет интерес исходный производственный код, выполняемый в Azure в качестве рабочей роли. Интересно, что изменение параметра параллелизма GC в app.config роли не имеет никакого эффекта. Возможно, Azure переопределяет настройки GC так же, как ASP.NET? Кроме того, выполнение тестового кода в WPF против консольного приложения приведет к несколько иным результатам выселения.