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