Мегаобучалка Главная | О нас | Обратная связь


Совместно используемые и частные сборки



2015-12-08 600 Обсуждений (0)
Совместно используемые и частные сборки 0.00 из 5.00 0 оценок




Сборки бывают двух типов: совместные и частные.

Частные сборки

Частные сборки являются самым простым видом. Как правило, они поставляются в комп­лекте с программным обеспечением и будут использоваться исключительно этим програм­мным обеспечением. Обычный способ поставки частных сборок - клиенту предоставляется приложение в виде исполняемого файла и набора библиотек, содержащих используемый приложением код.

Система гарантирует, что частные сборки не будут применяться другим програм­мным обеспечением, так как приложение может загружать только те частные сборки, которые расположены вместе с ним в одном каталоге или подкаталогах.

Обычно предполагается, что коммерческий программный продукт устанавливается в свой собственный каталог, тем самым исключается всякий риск удаления, модификации сборок или загрузки частной сборки, предназначенной для использования другим при­ложением. Поскольку частные сборки могут применяться только тем приложением, для которого они предназначены, у пользователя есть возможность контролировать исполь­зование сборок тем или иным программным обеспечением. Следовательно, требуется предпринимать меньше усилий по обеспечению безопасности, так как не существует ри­ска, например, того, что какое-то программное средство перепишет одну из сборок бо­лее новой версией (не считая, конечно, программ, написанных с целью умышленного нанесения ущерба). Также исключаются проблемы совпадающих, имен. Если классы в ча­стной библиотеке имеют те же названия, что и классы в другой частной библиотеке, это уже неважно, поскольку приложение будет видеть только один набор частных сборок.

Так как частная сборка полностью самоописываема, процесс инсталляции чрезвы­чайно прост. Необходимые файлы помещаются в указанный каталог на диске. Не требу­ется производить запись в реестре и другие подобные действия.

Этот процесс называют установкойс нулевым усилием.

Совместные сборки

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

Совместное использование требует учета следующих возможных опасностей:

· Коллизии имен, затрагивающие совместную сборку от другой компании, реализу­ющую типы, которые используют те же имена, что и ваша совместная сборка. Так как клиентский код теоретически может иметь доступ к обеим библиотекам, не исключено возникновение серьезных проблем.

· Опасность перезаписи сборки другой версией той же сборки, причем новая версия может оказаться несовместимой с уже имеющимся клиентским кодом.

 

Решение этих проблем заключается в размещении совместных сборок в специальном поддереве каталогов файловой системы, известном как кэш сборок.В отличие от част­ных сборок, общую сборку нельзя просто скопировать в соответствующий каталог, ее необходимо установить в кэш. Этот процесс может быть осуществлен с использованием нескольких утилит .NET; при этом проводятся определенные проверки сборки, а также создание небольшой структуры каталогов внутри кэша сборок, которая используется для обеспечения целостности сборки.

Во избежание риска коллизий имен совместные сборки именуются на основе крип­тографии с закрытым ключом (частные сборки имеют то же имя, что и основная про­грамма). Это имя называется строгим именем(strong name), оно является гарантиро­ванно уникальным и должно применяться приложениями, которые желают обращаться к совместной сборке.

Проблемы, связанные с риском перезаписи сборки, решаются указанием инфор­мации о версиях в манифесте сборки и обеспечением возможности сосуществования нескольких одноименных библиотек разных версий.

Пространства имен

Используя пространства имен, .NET избегает коллизий имен между классами.

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

Пространства имен - это нечто большее, чем простая группировка типов данных. Имена всех типов данных в определенном пространстве имен автомати­чески расширяются префиксом, образованным от названия пространства имен.

Также можно создавать вложенные пространства имен. Например, большинство базовых клас­сов .NET общего назначения расположено в пространстве имен System. Базовый класс Array находится в этом пространстве имен, поэтому его полное имя - System.Array.

.NET требует, чтобы все типы были определены в некотором пространстве имен.

 

Например, можно было бы разместить класс Customer в пространстве имен YourCompanyName. Тогда класс имел бы полное имя YоurCompanyName. Customer.

Если пространство имен не объявлено, то тип будет помещен в безымянное глобальное пространство имен.

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

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

При­мер синтаксиса в С# :

NamtSpaceYоurCompanyName.SalesServices

{

Class Customer

// и т.д

}

Области приложений

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

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


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

 

Вообще, любой процесс может обращаться к памяти только путем указания адреса в виртуальной памяти - процесс не имеет прямого доступа к физической памяти. Следо­вательно, один процесс ни в каком случае не может получить доступ к памяти другого процесса. Это дает гарантию того, что плохой код не сможет повредить ничего за пре­делами своего адресного пространства. (Отметим, что в Windows 9x это реализовано не так хорошо, как в NT/2000, и там существует теоретическая возможность нарушения работы Windows путем доступа к чужой памяти.)

Процессы служат не только для отделения друг от друга различных экземпляров ис­полняемого кода. В системах Windows NT/2000 они также образуют блок, с которым связаны привилегии доступа. Каждый процесс имеет свои собственные привилегии, которые показывают Windows, какие операции может выполнять данный процесс.

Процессы хорошо подходят для обеспечения безопасности (для исключения доступа к чужим участкам памяти и для разграничения по привилегиям), но их недостатком яв­ляется производительность. Нередко большое число процессов должно работать сооб­ща и иметь возможность связи друг с другом. Типичный пример, когда процесс вызывает СОМ-компонент, который является исполняемым файлом и, следовательно, должен быть запущен в отдельном процессе. То же самое происходит в СОМ, где приме­няются замещения. Так как процесс не может использовать память совместно еще с кем-то, то для передачи данных между процессами должны применяться сложные функ­ции переноса данных (marshalling). Это серьезно ухудшает производительность. Если необходимо, чтобы компоненты работали совместно и при этом не было потерь произ­водительности, единственный способ - использование DLL и работа всего кода в еди­ном адресном пространстве с риском того, что плохое поведение единственного компонента приведет к краху всей системы.


Области приложений разработаны как способ разделения компонентов с исключени­ем проблем производительности, связанных с передачей данных между процессами. Идея состоит в том, что каждый процесс делится на некоторое число областей приложения. В общем случае каждая область приложения соответствует одному приложению, а каж­дый исполняемый поток запускается в определенной области приложения:

 

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

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

Если приложению все же требу­ется общаться или обмениваться данными с приложениями, работающими в других областях приложений, то тогда должны использоваться удаленные службы .NET, пред­ставляющие собой различные базовые классы в пространстве имен System.Remoting.

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

 

J IT- компиляторы(Just-In-Time)

Компилятор JIT является ключевым средством платформы .NET и жизненно важной со­ставляющей в реализации попытки Microsoft сделать так, чтобы управляемый код работал с большей производительностью, чем неуправляемый.

Проблема производительности возникает из-за того, что код компилируется в промежу­точный язык, и это может стать неожиданностью для некоторых разработчиков. В конце концов, одним из недостатков Java является то, что процесс трансляции с байт-кода Java в исполняемый код в процессе выполнения программы означает потерю производительно­сти. Однако существует все же большая разница, заключающаяся в том, что байт-код Java интерпретируется, a IL компилируется.

Более того, JIT-компилятор компилирует не всю программу сразу (что может привести к излишне долгому запуску программы), а лишь кусок кода и именно тогда, когда он вызывается (отсюда название JIT-компилятора: Just-In-Time - вовремя).

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

Microsoft считает, что это более эффективный процесс, чем компиля­ция всей сборки сразу, так как велика вероятность того, что большая часть кода сборки не будет выполняться во время одного конкретного запуска программы. При использо­вании JIT- компилятора такой код вообще не придется компилировать.

Этим объясняется, почему исполнение управляемого кода на ILбудет почти таким же быстрым, как и исполнение родного машинного кода, но не объясняется, почему Microsoft ожидает подучить еще и улучшение по производительности. Дело в следую­щем: так как окончательная стадия компиляции происходит уже в процессе исполнения, JIT-компилятор точно знает, на каком процессоре будет работать программа. Это означа­ет, что код может быть оптимизирован под использование тех особенностей, которые предлагаются каждым конкретным процессором.

Традиционные компиляторы оптимизируют код, но они могут выполнять только оп­тимизацию, не зависящую от конкретного процессора. Это происходит из-за того, что современные компиляторы осуществляют компиляцию сразу в машинный код перед тем, как программа будет отправлена потребителю. Следовательно, компилятор не зна­ет, на каком процессоре будет исполняться код. Ему могут быть известны лишь общие сведения, что это будет процессор семейства х86 или процессор Alpha. Visual Studio 6, например, оптимизирует код для процессора Pentium, поэтому такой код не сможет вос­пользоваться преимуществами процессора Pentium III. Напротив, JIT-компилятор мо­жет выполнить ту же оптимизацию, что и Visual Studio 6, но вдобавок оптимизировать код для того процессора, на котором он будет исполняться.

 

Инструменты .NET

Помимо служб исполнения программы, .NET предоставляет ряд инструментов, которые призваны помочь в разработке приложений .NET:

Visual Studio.NET - интегрированная среда разработки, с помощью которой мож­но писать, компилировать и отлаживать код на всех языках .NET, включая С#, VB.NET, управляемый C++, страницы ASP.NET и неуправляемый код C++. (ILDASM опи­сывается в главе 8.)

·

 

· Компиляторы командной строки для С#, VB.NET и C++.

· ILDASM - утилитас оконным интерфейсом, которую можно использовать для просмотра содержимого сборки, включая манифест и метаданные.

 

Сборщик мусора

Сборщик мусора - это ответ .NET на проблемы управления памятью, в частности, на во­прос, связанный с перераспределением памяти, требующейся приложениям.

До сих пор в Windows использовались две методики перераспределения памяти, динамически запра­шиваемой процессами у системы: методика перераспределения памяти самим приложе­нием и применение в объектах счетчиков ссылок.

 

В дополнение Java использует сборщик мусора, аналогичный работающему в .NET.

Методика применения программного кода для перераспределения памяти использует­ся низкоуровневыми высокопроизводительными языками, например C++. Эта методика эффективна и имеет то преимущество, что ресурсы не используются сверх положенного срока.

Однако большим недостатком является значительное число ошибок. Код, кото­рый запрашивает память, должен в конце информировать систему о том, что память ему больше не требуется. В C++ для этого предусмотрено ключевое слово delete, кроме того, существуют различные функции API, предназначенные для той же цели. Программисты должны быть очень осторожны и внимательно следить за тем, чтобы освобождалась вся используемая память. Об этом нередко забывают, что приводит к утечкам памяти. Со­временные среды разработчика предоставляют инструменты для обнаружения утечек памяти, но эти ошибки все же очень сложно выявить, так как проявляются они лишь тогда, когда происходит утечка большого количества памяти и Windows в определенный момент просто отказывается выделить память процессу из-за ее отсутствия. К этому мо­менту работа всего компьютера может сильно замедлиться из-за потребления большого объема памяти.

Использование счетчиков ссылок применяется СОМ-объектами. Идея заключается в том, что каждый СОМ-объект поддерживает информацию о том, как много клиентов в данный момент используют ссылки на него. Когда число ссылок становится равным нулю, компонент уничтожает себя и освобождает память и ресурсы. Проблема здесь заключает­ся в том, что СОМ-объект рассчитывает на корректное поведение клиентов, которые дол­жны сообщать ему об окончании своей работы с объектом (что осуществляется путем вызова метода IUnknown. Release ()). Стоит только одному из клиентов не сделать этого, и объект останется в памяти. В некоторых случаях это является потенциально еще более серьезной проблемой, чем простая утечка памяти в C++, так как СОМ-объект может суще­ствовать в своем собственном процессе, а это означает, что он никогда не будет удален си­стемой (в случае утечек памяти система, по крайней мере, может освободить всю память по завершении процесса).

Какое же решение применяется в .NET?

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

Посмотрим, как это работает на практике, воспользовавшись фрагментом кода на С#:

{

TextBox UserInputArea; // Объявили переменную

UserInputArea = new TextBox(); // В куче создается экземпляр объекта TextBox

TextBox TextBoxCopy = UserInputArea; // Объявление с инициализацией

 

// Допустим, что сборщик мусора вызван здесь

// Обработка данных

}

// Теперь UserInputArea и TextBoxCopy находятся вне зоны видимости кода

//Допустим, что здесь снова был вызван сборщик мусора

 

Код начинается с объявления переменной типа TextBox. Эта переменная имеет имя UserInputAreа.

TextBox является типом по ссылке. Это означает, что UserlnputArea содержит адрес, и нам необходимо отдельно создать экземпляры объектов TextBox в куче, что делается в следующей строке.

Затем мы объявляем еще одну переменную, TextBoxCopy, и присваиваем ей значение UserlnputArea, т.е. она тоже ссылается на TextBox.

Теперь допустим, что это происходит в тот момент, когда вызывается сборщик мусо­ра. Просматривая ссылки по коду, он обнаружит, что обе переменные ссылаются на TextBox. Очевидно, что объектTextВохдо сих пор используется и должен оставаться в куче. Сборщик мусора не только удаляет объекты - он может упорядочивать кучу для по­вышения производительности. Поэтому существует вероятность того, что он изменит местоположение данных для объекта TextBox. Если это будет сделало, то он обновит адреса, содержащиеся в UserlnputArea и txtBoxCopy.

Затем переменные UserlnputArea и txtBOxCopy выходят из области видимости. Допустим, что больше никакие переменные не ссылаются на TextBox и что в этот мо­мент снова вызывается сборщик мусора. Теперь он обнаружит, что существует область в куче, используемая для хранения TextBox, и что на эту область не ссылается ни одна из видимых переменных. Исходя из этого, сборщик мусора решит, что TextBox больше не требуется, и удалит его.

Отметим, что данный механизм совершенно безопасен: если наTextBox нет ссылок, то не существует законного пути, посредством которого код сможет снова получить до­ступ к TextBox. Промежуточный язык не обеспечивает каких-либо безопасных спосо­бов получения ссылки на объект в куче, кроме как его создание или копирование уже существующей ссылки. Если нет ссылки, которую можно скопировать, он не способен законно получить ссылку на существующий объект.

Здесь мы говорим "законно", так как теоретически можно написать небезопасный код на С# или C++, который будет использовать указатели, арифметику указателей и преобразование типов для повторного получения ссылки на TextBox. Однако здесь не видно никаких причин, по которым кто-то захотел бы сделать это, кроме как для того, чтобы продемонстрировать саму возможность подобных действий,- определенно, это не в духе методологии .NET. Ссылку можно получить более простым способом - написав код, который никогда не потеряет ее!

Сборка мусора работает потому, что промежуточный язык был спроектирован для облесения этого процесса. Требуется, первое, чтобы ссылки на существующие объекты нельзя было получить иначе, кроме как копированием имеющихся ссылок на объекты, и второе, чтобы промежуточный язык был безопасным по типам. В этом контексте под бе­зопасностью по типам понимается то, что если существует ссылка на объект, то в этой ссылке присутствует достаточно информации для точного определения типа объекта.

Механизм сборки мусора невозможно было бы применять с таким языком, как неуп­равляемый C++, поскольку C++ допускает свободное преобразование типов указателей. Это означает, что ни одна из программ, просматривающих код, не сможет определить по значениям указателей, какие участки кучи используются на данный момент. Как уже отмечалось ранее, IL допускает применение указателей в небезопасном коде, а также позволяет преобразовывать тип указателя. Однако в IL существуют жесткие ограниче­ния на использование указателей, которые были разработаны таким образом, чтобы их применение в коде не конфликтовало с требованиями сборщика мусора. Б частности, указатели не могут указывать на ссылочные объекты.

Важной особенностью сборки мусора является то, что это недетерминированный процесс. Нельзя сказать, когда будет вызван сборщик мусора: он вызывается тогда, когда среда исполнения .NET решает, что его необходимо вызвать. Очевидно, что чем больше требований программа предъявляет по части памяти, тем чаще будет вызываться сбор­щик мусора. Сборщик мусора можно вызвать из программы вручную с помощью базово­го класса .NET System.GC. Это можно сделать, например, в точке, где код заканчивает работу с большим числом переменных. В большинстве ситуаций, однако, придется дове­риться среде исполнения .NET, которая сама будет вызывать сборщик мусора при необ­ходимости.

 



2015-12-08 600 Обсуждений (0)
Совместно используемые и частные сборки 0.00 из 5.00 0 оценок









Обсуждение в статье: Совместно используемые и частные сборки

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Как построить свою речь (словесное оформление): При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою...
Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ...
Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней...
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (600)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.012 сек.)