Домены приложений и сборки
Обновлен: Ноябрь 2007
В этом разделе описывается связью между доменами приложений и сборками. Чтобы выполнить код сборки, ее необходимо загрузить в домен приложения. Как правило, для запуска приложения в домен приложения необходимо загрузить несколько сборок.
Способ загрузки определяет, можно ли использовать JIT-скомпилированный код сборки в нескольких доменах приложений в процессе и можно ли выгружать сборку из процесса.
Если сборка загружается как нейтральная к домену, то все домены приложений с одним набором разрешений безопасности могут совместно использовать JIT-скомпилированный код, что снижает требуемый для приложения объем памяти. Однако сборку нельзя выгружать из процесса.
Если сборка не загружается как нейтральная к домену, она должна быть JIT-скомпилирована в каждом домене приложения, в который она загружается. Однако сборку можно выгрузить из процесса, выгрузив все домены приложений, в которые она загружается.
Следует ли загружать сборки как нейтральные к домену, определяется в хост-приложении среды выполнения при загрузке среды выполнения в процесс. Для управляемых приложений примените атрибут LoaderOptimizationAttribute к методу точки входа процесса и укажите значение из связанного перечисления LoaderOptimization. Для неуправляемых приложений, в которых размещается среда CLR, укажите соответствующий флаг при вызове метода Функция CorBindToRuntimeEx.
Существует три варианта загрузки нейтральных к домену сборок.
SingleDomain не загружает сборки как нейтральные к домену, за исключением Mscorlib, которая всегда загружается как нейтральная к домену. Этот вариант называется однодоменным, поскольку обычно он используется, когда в хост-приложении запускается только одно приложение в процессе.
MultiDomain загружает все сборки как нейтральные к домену. Этот вариант используется при наличии нескольких доменов приложений, в каждом из которых выполняется одинаковый код.
MultiDomainHost загружает сборки со строгими именами как нейтральные к домену, если они и все их зависимости установлены в глобальном кэше сборок. Другие сборки загружаются и JIT-компилируются отдельно для каждого домена приложения, в котором они загружаются, поэтому могут выгружаться из процесса. Этот вариант используется при работе нескольких приложений в одном процессе или при наличии набора сборок, которые являются общими для нескольких доменов приложений, и сборок, которые должны выгружаться из процесса.
JIT-скомпилированный код нельзя сделать общим для сборок, загруженных в контекст загрузки с помощью метода LoadFrom класса Assembly или загруженных из образов с помощью перегрузок метода Load, задающего байтовые массивы.
Сборки, которые были скомпилированы в машинный код с помощью Генератор образов в машинном коде (Ngen.exe), могут совместно использоваться доменами приложений, если они загружены как нейтральные к домену при первой загрузке в процесс.
JIT-скомпилированный код для сборки, содержащей точку входа приложения, может быть общим, только если все его зависимости могут использоваться совместно.
Сборка, нейтральная к домену, может JIT-компилироваться более одного раза. Например, когда наборы разрешений безопасности двух доменов приложений отличаются, они не могут совместно использовать один и тот же JIT-скомпилированный код. Однако каждая копия JIT-скомпилированной сборки может использоваться совместно с другими доменами приложений, имеющими такой же набор разрешений.
При принятии решения о том, следует ли загружать сборки как нейтральные, осуществляется компромисс между сокращением расхода памяти и производительностью.
Доступ к статическим данным и методам для нейтральных к домену сборок осуществляется медленнее из-за необходимости изоляции сборок. Каждый домен приложения, обращающийся к сборке, должен обладать собственной копией статических данных, чтобы избежать ссылок на объекты в статических полях, пересекающих границы домена. В результате среда выполнения содержит дополнительные правила для перенаправления вызывающего объекта к соответствующей копии статических данных или метода. Эти дополнительные правила замедляют вызов.
При загрузке сборки как нейтральной к домену необходимо найти и загрузить все зависимости сборки, поскольку зависимость, которую нельзя загрузить как нейтральную, не позволяет загрузить сборку как нейтральную.