Сборки .NET JIT на общих страницах

При запуске приложения .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, и у меня заканчиваются идеи по поисковым запросам, чтобы попытаться решить эту проблему; кто сделает мой день лучше, помогая устранить это ужасное нытье чувство «Я не понимаю, что происходит»!?! :)


person allgeek    schedule 05.04.2009    source источник
comment
За исключением каких-либо убедительных доказательств того, что NGen действительно поможет с использованием памяти (и незначительным влиянием времени запуска в нашей среде), мы решили не продолжать создание образов наших сборок в машинном коде. Я все же хотел бы знать, почему мы наблюдаем такое неожиданное поведение!   -  person allgeek    schedule 08.04.2009


Ответы (1)


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

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

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

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

person Bill Wert - MSFT    schedule 18.04.2009
comment
Спасибо за ответ! Я разобью все и сделаю несколько более простых тестов, но я не видел таких же результатов. И из того, что я прочитал (и из публикации в блоге, на которую я ссылался), я действительно должен увидеть разницу в страницах модулей. AFAIK, CLR по-прежнему необходимо читать метаданные для поддержки отражения, проверки политик CAS и т. Д .; NGEN этого не устраняет. Поскольку это приложение на базе TS-сервера, которое запускают многие пользователи, использование памяти имеет решающее значение, а время холодного запуска практически не имеет значения. - person allgeek; 18.04.2009
comment
Без проблем! Доступ к метаданным для Reflection и тому подобного является ленивым - ничего не загружается с нетерпением для поддержки этих сценариев. Я понимаю, что в сценарии TS использование памяти является ключевым фактором. Я рекомендую вам прочитать эту статью: msdn.microsoft.com/en-us/ magazine / cc163610.aspx, если нет. При повторном просмотре страниц модуля обратите внимание на столбец WS в vmmap, а не на size / commited. WS - это реальный размер используемой страницы, я видел от 2,3 МБ до 32 КБ. Удачи! - person Bill Wert - MSFT; 19.04.2009