В каких обстоятельствах процессы .NET и AppDomains будут совместно загружать сборки в память?

Я ищу дополнительную информацию о том, когда и как приложения .NET совместно используют загруженные сборки. Я заинтересован в совместном использовании процессов ОС, но и между AppDomains в рамках одного процесса. Совместное использование сборок снижает использование системной памяти, избегая наличия нескольких копий одной и той же сборки в памяти, я полагаю, что это основное преимущество, но было бы интересно узнать, есть ли другие преимущества и/или последствия.

Резюме того, что я узнал до сих пор...

  • Sysinternals process explorer можно использовать для перечисления процессов AppDomains.NET и сборок, загружаемых в каждый AppDomain.

  • Процесс .NET всегда загружает сборку "core" в AppDomain под названием "SharedDomain" (разумно предположить, что это общий доступ между AppDomains в текущем процессе).

  • Диспетчер задач и проводник процессов сообщают не несущественные номера использования памяти для "Working Set Shared" и "Working Set Shareable", но не ясно, что общего. (Является ли это "ядром" сборок в общем домене приложения? Также существуют другие [неядерные] сборки?

  • В простой тесте я запустил две копии автономного .NET-приложения и подключил отладчик Visual Studio для каждого. В представлении "Модули" показаны загруженные сборки и их адреса в памяти. В моем тестовом случае каждый загруженный модуль находился по тому же адресу в двух процессах. (Указывает ли это на общий доступ или это виртуальное адресное пространство, которое не обязательно разделяется?)

  • ASP.NET 4.5 поддерживает совместное использование сборок через механизм, называемый ассемблером (см. Посмотрите на совместное использование общих ассемблий в ASP.NET 4.5, Совместное использование общих сборок, Совместное использование общих сборок с помощью aspnet_intern.exe). Похоже, что он работает, настраивая символические ссылки файловой системы (символические ссылки), чтобы различные веб-приложения указывали на общую папку bin, поэтому возникает вопрос о том, просто ли ASP.NET использует символические ссылки для запуска стандартного поведения совместного использования сборки в .NET., или существует ли что-то более конкретное для ASP.NET и IIS AppPools.

Примечание. На машине с установленной Visual Studio 2013 aspnet_intern.exe можно найти в:

C:\Program Files (x86)\Microsoft SDK\Windows\v8.1A\bin\NETFX 4.5.1 Инструменты \

В более поздних версиях .NET и Windows Server были улучшены время запуска ASP.NET и использование памяти; См. ASP.NET App Suspend - отзывчивый общий веб-хостинг .NET, Улучшения производительности для сценариев общего хостинга ASP.NET в .NET. 4.5, но я не уверен, насколько актуальны эти изменения для этого вопроса.

Совместное использование ASP.NET также описано в книге Представляем .NET 4.5.

Также интересно узнать, является ли JIT-код общим или нет, поскольку загруженная сборка состоит из MSIL, ресурсов, метаданных и т.д., и дальнейшая память должна быть выделена, когда код JITted.

Также обсуждается совместное использование сборок в компактной структуре (Мы верим в совместное использование, Блоги MSDN, Абхинаба Басу)

--- --- ОБНОВЛЕНИЕ

Я использовал инструмент sysinternals VMMap, чтобы изучить два AppPools, один с настройкой межсетевого соединения asp.net, а другой без него. Я также "коснулся" тестовой страницы aspx, чтобы заставить ASP.NET загружать все сборки (а global.asax работает с небольшим количеством кода, поэтому вызывает некоторые JITting).

Показанные значения использования памяти для двух AppPools очень схожи, рабочий набор, WS Private и WS Shareable по существу одинаковы. Однако WS Shared намного больше в "интернировании" AppPool. Это было неожиданным (для меня), поскольку нет другого процесса для совместного использования, но VMMap показывает, что блоки памяти (помечены как ".text" и с защитой Execute/Read), которые отображаются как обмен памяти в интернирующем AppPool, тогда как одна и та же сборка в другом AppPool не используется. Моя интерпретация этого заключается в том, что блоки виртуальной памяти в процессе отображаются в одну и ту же физическую память и затем сообщаются как "WS Shared".

ASLR

Что касается рандомизации макета пространства сборки. Средство VMMap показывает много блоков памяти с типом "Image (ASLR)". ASLR рандомизирует местоположение сборок в памяти, чтобы помешать вредоносному ПО, и я задался вопросом, не мешало ли это правительству работать в сборке. Отключение ASLR для машины с помощью инструмента EMET привело к тому, что адреса ассемблера были более регулярными, но не меняли номера зарегистрированных номеров, поэтому, похоже, это не влияет на сборку интернирование. Стоит отметить, что VMMap все еще показывал изображения с ASLR против них, что, как я подозреваю, просто означает, что сборка/изображение помечены как поддержка/разрешение ASLR, а не ASLR.

Ответы

Ответ 1

В одном случае, когда происходит совместное использование сборки, сборки скомпилированы в собственный код с помощью ngen.exe. Позвольте мне привести "CLR через С#" (глава 1)

Инструмент NGen.exe интересен в двух сценариях:

...

Уменьшение рабочего набора приложений - если вы считаете, что сборка будет загружаться одновременно в несколько процессов, запуск NGen.exe на этой сборке может уменьшить набор рабочих приложений. Причина в том, что инструмент NGen.exe скомпилирует IL к собственному коду и сохраняет результат в отдельный файл. Этот файл может быть отображен в память в несколько процессов адресные пространства одновременно, позволяя совместно использовать код; не каждый процесс нуждается в собственной копии кода.