Sources.RU Magazine Поиск по журналу
 

TopList

Домены приложений в .NET Framework

Автор: DeVoid

Домены приложений (application domains) - важное нововведение в .NET, предназначенное для снижения накладных расходов, связанных с запуском приложений, которые должны быть изолированы друг от друга, но при этом нуждаются во взаимодействии между собой. Классический пример - приложения Web-сервера, которые могут совместно отвечать на множество запросов браузеров, а потому должны, вероятно, иметь экземпляры компонента, ответственного за параллельное обслуживание таких запросов.

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

До последнего времени изоляция кода была возможна только между процессами. Когда запускается новое приложение, оно работает в контексте процесса. Windows изолирует процессы друг от друга посредством адресных пространств. Идея состоит в том, что каждому процессу предоставляется 4Гбайт виртуальной памяти, в которой он сохраняет свои данные и исполняемый код (4Гбайт - это для 32-разрядных систем, 64-разрядные системы используют больший обьем памяти). Windows вводит дополнительный уровень переадресации, благодаря которому эта виртуальная память отображается на определенную область реальной физической памяти или дисковое пространство. Каждый процесс получает свое отображение, при этом гарантируется, что не случится никакого перекрытия между реальными физическими областями памяти, выделенными каждому из них (Рис.1).


Домены приложений в .NET Framework

Рис.1. Отображение виртуальной памяти процессов на физическую память

В общем случае любой процесс может обратиться к памяти только по адресу виртуальной памяти - процессы не имеют прямого доступа к физической памяти. А потому попросту невозможно одному процессу получить доступ к памяти, выделенной для другого. Это гарантирует, что никакой код, который "плохо" себя ведет, не сможет повредить ничего вне собственного адресного пространства.

Но процессы не только служат для изоляции экземпляров работающего кода друг от друга. В системах Windows NT/2000/XP/2003 они также формируют элементы, которым назначаются права доступа и привилегии безопасности. Каждый процесс снабжен своим собственным маркером доступа (security token), который указывает системе, какие именно действия разрешено выполнять этому процессу.

Хотя процессы удобны для обеспечения безопасности, все же они имеют серьезный недостаток, связанный с производительностью. Часто бывает так, что множество процессов работают вместе и потому нуждаются в общении друг с другом. Очевидный пример этого - это когда процесс вызывает компонент COM, который является исполняемым, а потому запускает свой собственный процесс. То же случается в COM, когда используется "заместитель" (surrogate). Поскольку процесс на может разделить память с другими, должен быть применен сложный процесс маршаллинга для копирования данных между процессами. В результате ощутимо страдает производительность. Если вам нужно, чтобы компоненты работали вместе без снижения производительности, то следует использовать компоненты, основанные на DLL, чтобы все работало в одном адресном пространстве, подвергаясь риску, что один "плохо" ведущий себя компонент разрушит все остальные. Домены приложений спроектированы как способ разделения компонентов без сопутствующих проблем снижения производительности, связанных с передачей данных между процессами. Идея заключается в том, что каждый процесс разделяется на несколько доменов приложений. Каждый домен приложения приблизительно соответствует отдельному приложению, и каждый поток исполнения запускается в определенном домене приложения. (Рис.2).


Домены приложений в .NET Framework

Рис.2. Домены приложений

Если разные исполняемые программы запускаются в одном пространстве процесса, то очевидно, что они могут легко разделять общие данные, потому что теоретически в состоянии напрямую видеть данные друг друга. Однако, хотя такая возможность существует в принципе, CLR обеспечивает, чтобы этого не случилось на практике, инспектируя код каждого работающего приложения, дабы гарантировать, что код не выйдет за пределы области своих собственных данных. На первый взгляд этот трюк кажется почти невозможным - в конце концов, как вы можете знать, что собирается делать программа, до того как запустите ее?

На самом деле, обычно сделать это возможно, благодаря строгой защите типов IL. В большинстве случаев, если только код не применяет небезопасных средств, таких как указатели, то используемые им типы данных гарантируют, что не произойдет никаких неправильных обращений к памяти. Например, типы массивов в .NET предусматривают проверку границ, чтобы не допустить никаких действий за границами массива. Если функционирующее приложение нуждается во взаимодействии или разделении данных с другим работающим приложением, оно должно делать это посредством вызова удаленных служб (remote services).

Код, верифицированный на предмет того, что он не может обращаться к памяти вне домена приложения (кроме как явным использованием удаленных механизмов), называют безопасным к типам в памяти (memory safe-type). Такой код может быть безопасно запущен параллельно с другим безопасным к типам кодом в разных доменах приложений в пределах одного процесса.

С уважением, DeVoid!
( Cайт автора )



Если у Вас возникли проблемы, вопросы или пожелания к статье – милости просим в тему поддержки этой статьи.




 Design by Шишкин Алексей (Лёха)  ©2004-2008 by sources.ru