Сборки .NET JIT на разделяемых страницах - PullRequest
3 голосов
/ 06 апреля 2009

При запуске приложения .NET 2.0 WinForms в среде служб терминалов я вижу некоторые неожиданные результаты, которые я не могу полностью объяснить. Все, что я прочитал, указывало на то, что сборки JIT (то есть не использующие NGen для создания собственных изображений) приводят к тому, что все пространство кода сохраняется на личных страницах, что увеличивает размер рабочего набора / нагрузку на память. Однако фактические результаты (проверенные с помощью Process Explorer, VMMap и WinDbg) показывают, что даже сборки JIT действительно размещаются на разделяемых страницах (и действительно совместно используются, когда запущено несколько экземпляров приложения, даже под отдельными TS сессии / пользователей).

Может кто-нибудь объяснить, почему это может быть? Это выполняется в среде сервера W2K8, поэтому ASLR объясняет, почему отсутствие конкретных базовых адресов для каждой сборки и результирующий перебазирование не вызывают проблем. Тем не менее, кажется, тот факт, что это не собственные образы PE, должен привести к тому, что код для этих сборок будет храниться на личных страницах.

Это было обнаружено, когда мы начали исследовать использование NGen для уменьшения нагрузки на память, но на самом деле обнаружили, что он увеличил размер рабочего набора - поскольку сборки JIT уже были общими.

Самая последняя ссылка, которую я нашел, находится здесь, что опять-таки отличается от наших фактических результатов:

http://blogs.msdn.com/morgan/archive/2009/03/07/developing-net-applications-for-deployment-on-terminal-services-or-citrix.aspx

Редактировать: Я должен добавить, что с момента первого опубликования вопроса больше экспериментов с тестовыми блоками Windows Server 2003 также, по-видимому, показывают, что JIT-сборки могут использоваться совместно между процессами. Я все еще в замешательстве относительно того, почему все советы, которые я могу найти, указывают на то, что NGen требуется, но все реальные данные противоречат этому. Я очень надеюсь, что эксперты здесь смогут пролить свет.

Спасибо!

Редактировать: Я вычистил все свои книги .NET / CLR и исчерпал идеи для поисковых запросов, чтобы попытаться решить эту проблему; кто собирается сделать мой день, помогая устранить это ужасное ноющее чувство "я не понимаю, что происходит"!?! :)

1 Ответ

4 голосов
/ 18 апреля 2009

Я думаю, что вы смотрите прямо на страницах модуля. Когда вы JIT-код, он не будет отображаться в вашей DLL - он отображается в памяти, выделяемой во время выполнения. Страницы модуля, на которые вы просматриваете, - это в основном метаданные и IL, поэтому они все еще доступны для совместного использования.

В качестве эксперимента я написал небольшую программу, которая генерирует статические методы 30 КБ и вызывает их. В моей системе JIT-версия этой программы имеет 8,2 МБ собственной выделенной памяти, а версия NGEN - 3,8.

Однако даже на страницах вашего модуля NGEN помогает с использованием памяти. Когда среда выполнения может загрузить изображение NGEN, ей не нужно читать метаданные вашего модуля, чтобы JIT код. JIT-версия моего тестового приложения использует 2,3 МБ рабочего набора. Версия NGEN использует 32 килобайта.

NGEN также должен помочь вам при запуске. Воздействие на время теплого запуска может быть незначительным, но влияние на время холодного запуска (сохранение чтения всех этих страниц с диска) может быть заметным.

...