Почему (и как) кэш ASP.NET хранится в неуправляемой памяти?
ОК, все, что вы, эксперты ASP.NET: я использовал рефлектор для просмотра реализации ASP.NET Cache (который находится на HttpRuntime.Cache
и HttpContext.Current.Cache
) использует Hashtable
внутри, чтобы сохранить кеш.
Однако данные сохраняются в неуправляемой памяти. Это очень странно, потому что я не мог видеть, что данные хранятся в неуправляемой памяти. Однако, написав очень простое веб-приложение, которое вставляет кусок массива байтов в кеш, мы можем видеть это:
![enter image description here]()
- Частные байты: 460 МБ
- Байт во всех кучах: 150 МБ
= >
Управляемая память: 150 МБ
Неуправляемая память: 310 МБ
Таким образом, в основном я вызываю приложение много раз (каждое увеличение - 1000х запросов, каждый из которых кладет пул буфера 64 Кбайт [] в кеш). Таким образом, тот, который вырос больше всего private bytes (общая память) вместо байтов во всех кучах (управляемая память). Однако я ожидаю, что управляемая память будет расти в соответствии с общей памятью, поскольку я добавляю объекты в управляемую кучу с помощью Hashtable.
Можете ли вы объяснить это поведение?
UPDATE
Как сказал Саймон, байты во всех значениях кучи меняются только после сбора мусора - я изменил код, чтобы вызвать сборку мусора, и обновил счетчики. Увеличение памяти Gen 2 Heap в точности совпадает с объемом добавленной памяти. Однако неуправляемая память все еще намного выше. В этом примере куча 2 составляла всего 96 МБ, а общая память - 231 МБ.
![enter image description here]()
Ответы
Ответ 1
# Bytes in all Heaps
обновляется только тогда, когда выполняется сбор мусора, а Private Bytes
доступен с гораздо более высокой скоростью обновления. (Я не уверен, откуда это число, внутри, и как часто оно обновляется.)
Количество Private Bytes
увеличивается сразу после 17:42:45. Кажется, что эта сумма соответствует скачку стоимости # Bytes in all Heaps
примерно в 17:43:10. Похоже, что за 20-25 секунд до сбора мусора и обновления счетчика # Bytes in all Heaps
.
Трудно решить, как распределяются распределения памяти из нескольких минут производительности счетчиков производительности, представленных на скриншоте.;) Продолжайте тестирование и посмотрите, как ваши ожидания будут работать в течение более длительного периода времени.
TL; DR: количество управляемых байтов должно соотноситься с частными байтами, но управляемый счетчик будет обновляться только во время сбора мусора.
Небольшое примечание от OP: Как говорится в этом ответе, отставание в памяти может быть полностью объяснено отставанием GC. Тот факт, что неуправляемая память также поднимается, не был моим вопросом. Так что спасибо @Simon.