Как правильно писать тесты 46 Цикл разработки 46 Структура проекта с тестами 51 Утверждения (Asserts) 52 Утверждения в форме ограничений 54 Категории 56

Вид материалаТесты

Содержание


IL и верификация
Небезопасный код
IL и защита интеллектуальной собственности
NGen.exe — генератор объектного кода
Сокращение времени запуска приложения
Уменьшение рабочего объема приложения
Подобный материал:
1   ...   5   6   7   8   9   10   11   12   ...   47

IL и верификация




Главное достоинство IL не в том, что он позволяет абстрагироваться от конкретного типа процессора, а в надежности и безопасности приложений. При компиляции IL в машинный код CLR выполняет верификацию, в процессе которой проверяется, все ли «безопасно» делает высокоуровневый IL-код: например, нужное ли число параметров передается методу и корректны ли их типы, правильно ли используются возвращаемые методами значения, имеют ли все методы операторы возврата и т. д. Все необходимые для верификации сведения о методах и типах есть в метаданных управляемого модуля.


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

Между тем, верифицировав управляемый код, можно быть уверенным, что он не обратится некорректно к памяти и не повлияет на код другого приложения. Это значит, что можно выполнять несколько управляемых приложений в едином виртуальном адресном пространстве Windows.


Поскольку процессы в Windows требуют массу ресурсов ОС, наличие множества процессов отрицательно сказывается на производительности и ограничивает доступные ресурсы. Уменьшение количества процессов за счет запуска нескольких приложений в одном процессе ОС увеличивает производительность и снижает потребности в ресурсах, но никак не в ущерб надежности. Это еще одно преимущество управляемого кода перед неуправляемым.

CLR предоставляет возможность выполнения множества управляемых приложений в одном процессе ОС. Каждое управляемое приложение связано с доменом приложения (AppDomain). По умолчанию каждый управляемый ЕХЕ-модуль работает в собственном, отдельном адресном пространстве, где есть только один AppDomain. Однако процесс, являющийся хостом CLR (например, Internet Information Services (IIS)), может выполнять домены приложений в одном процессе ОС.


Небезопасный код


По умолчанию компилятор С# Microsoft генерирует безопасный код, то есть такой, безопасность которого поддается проверке. Вместе с тем компилятор С# Microsoft позволяет разработчикам писать небезопасный код, которому разрешается работать непосредственно с адресами памяти и управлять байтами в этих адресах. Это очень мощная возможность, обычно полезная при взаимодействии с неуправляемым кодом или необходимости добиться максимальной производительности при выполнении критически важных алгоритмов.

Однако использование небезопасного кода довольно рискованно: он способен разрушить структуры данных и воспользоваться существующими или создать новые бреши в системе безопасности. По этой причине компилятор С# требует, чтобы все методы, содержащие небезопасный код, выделялись ключевым словом unsafe, а исходный код компилировался с параметром /unsafe компилятора.


По умолчанию явно установленным сборкам на компьютере пользователя предоставляется полный уровень доверия, то есть выдается «карт-бланш», в том числе на выполнение небезопасного кода. Вместе с тем, по умолчанию сборкам, выполняемым через интрасеть или Интернет, разрешение на выполнение небезопасного кода не предоставляется.


IL и защита интеллектуальной собственности


Некоторые люди озабочены тем, что IL не обеспечивает достаточной защиты интеллектуальной собственности. Иначе говоря, они считают, что можно создать управляемый модуль, а кто-то другой, используя такие инструменты, как IL-дизассемблер, легко восстановит точный код исходного приложения.

IL, действительно, язык гораздо более высокого уровня, чем другие языки ассемблеров, и восстановить исходный алгоритм из IL-кода относительно просто. Однако при реализации кода, работающего на стороне сервера (Web-сервисов, приложений Web Forms или хранимых процедур), управляемый модуль размещается на сервере. Поскольку никто, кроме работников компании, не имеет доступа к модулю, ни один посторонний не сможет использовать какие-либо утилиты для просмотра IL-кода — интеллектуальная собственность полностью защищена.

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

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


NGen.exe — генератор объектного кода


Поставляемая в составе .NET Framework утилита NGen.exe служит для компиляции IL-кода в команды процессора при установке приложения на машине пользователя. Поскольку код компилируется во время установки, JIT-компилятор среды CLR не задействуется, что в принципе способствует повышению производительности приложения. NGen.exe наиболее полезна для решения двух задач.

Сокращение времени запуска приложения Код приложения уже преобразован в машинные команды, поэтому потребность в компиляции во время выполнения отпадает.

Уменьшение рабочего объема приложения. Если предположить, что сборка будет одновременно загружаться во многие процессы или домены AppDomains, предварительная компиляция с применением NGen.exe позволит уменьшить рабочее множество приложения. Причина в том, что скомпилированный утилитой NGen.exe машинный код сохраняется в отдельном файле, который в дальнейшем может проецироваться из памяти в адресные пространства многих процессов и совместно использоваться ими. Отпадает необходимость каждому процессу или домену AppDomain иметь собственную копию кода.

Когда установщик вызывает NGen.exe для обработки приложения или отдельной сборки, в машинный код компилируется соответственно IL-код всех сборок приложения или одной выбранной сборки. Созданный утилитой файл сборки, содержащий только машинный код, помещается в одну из подпапок установочной папки Windows, например в C:\Windows\Assembly\NativeImages_ v2.0.50727_32. Имя каталога содержит версию CLR и информацию, указывающую на целевую платформу машинного кода — х86 (32-разрядная версия Windows), х64 (64-разрядная версий Windows).

Всякий раз при запуске файла сборки CLR проверяет наличие сгенерированного утилитой NGen.exe файла с машинным кодом. При наличии нужного NGen-файла CLR будет использовать скомпилированную программу, и методы во время выполнения компилироваться на будут. Однако, если такой файл не обнаруживается, JIT скомпилирует IL-код в обычном порядке.