Справочная информация
Я сейчас сравниваю производительность NancyFx и ServiceStack.NET, работающих под управлением IIS 7 (тестирование на хосте Windows 7).И то, и другое безумно быстро - локальное тестирование каждой инфраструктуры обрабатывает более 10000 запросов в секунду, а ServiceStack работает примерно на 20% быстрее.
Проблема, с которой я сталкиваюсь, заключается в том, что ASP.NET, кажется, кэширует ответы длякаждый уникальный запрос URI от HttpHandler быстро приводит к значительному увеличению нагрузки на память (3+ ГБ) и перегружает сборщик мусора (~ 25% времени, затрачиваемого GC).До сих пор я не смог отключить кэширование и сборку объектов и ищу предложения о том, как отключить это поведение.
Подробности
Цикл запроса в основном выглядит следующим образом:
for i = 1..100000:
string uri = http://localhost/users/{i}
Http.Get(uri)
Ответ представляет собой простой объект JSON, отформатированный как {UserID: n}.
Я взломал WinDBG, и для каждого запроса есть:
- Один
System.Web.FileChangeEventHandler
- Два
System.Web.Configuration.MapPathCacheInfos
- Два
System.Web.CachedPathDatas
- Три
System.Web.Caching.CacheDependencys
- Пять
System.Web.Caching.CacheEntrys
Очевидно, что именно эти элементы кеша заставляют меня поверить, что это проблема переполнения кеша (я бы хотел избавиться от 150 000 непригодных для использования объектов!).
Что я пробовалfar
- В IIS 'HTTP Resonse Headers' установите для параметра «Expire Web content» значение «немедленно».
В файле web.config
<system.web>
<caching>
<outputCache enableOutputCache="false" enableFragmentCache="false"/>
</caching>
</system.web>
Также в web.config (и во многих вариациях политик, в том числе ни одного).
<caching enabled="false" enableKernelCache="false">
<profiles>
<add policy="DontCache" kernelCachePolicy="DontCache" extension="*/>
</profiles>
</caching>
Просматривал исходный код фреймворковчтобы увидеть, могут ли быть встроены какие-либо "функции", которые будут использовать кэширование ASP.NET.Хотя существуют помощники для кэширования, они являются частными для самой платформы и, по-видимому, не используют кэширование ASP.NET.
Обновление # 1
Копание в отражателе I 'мы обнаружили, что установка значения UrlMetadataSlidingExpiration
в ноль устраняет большую часть чрезмерного использования памяти за счет сокращения пропускной способности на 50% (класс FileAuthorizationModule кэширует FileSecurityDescriptors, который должен быть несколько дорогим для генерации, когда UrlMetadataSlidingExpiration
не равен нулю).
Это делается путем обновления web.config и размещения следующего в:
<hostingEnvironment urlMetadataSlidingExpiration="00:00:00"/>
Я собираюсь попытаться полностью отключить запуск FileAuthorizationModuleЕсли возможно, посмотреть, поможет ли это.Однако ASP.NET по-прежнему генерирует 2 * N MapPathCacheInfo
и CacheEntry
объектов, поэтому память все еще расходуется, только с гораздо меньшей скоростью.
Update # 2
Другойполовина проблемы - та же самая проблема, как описано здесь: Предотвращение заполнения множества различных URL-адресов MVC ASP.NET Cache .Настройка
<cache percentagePhysicalMemoryUsedLimit="1" privateBytesPollTime="00:00:01"/>
помогает, но даже при этих очень агрессивных настройках использование памяти быстро возрастает до 2,5 ГБ (по сравнению с 4 ГБ).В идеале эти объекты никогда бы не создавались.В противном случае я могу прибегнуть к хакерскому решению использования отражения для очистки кешей (все эти записи являются «частными» и не перечисляются при переборе по общему кешу).