Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Оригинал: https://blogs.msdn.com/robtiffany/archive/2009/04/09/memmaker-for-the-net-compact-framework.aspx
Кто-нибудь ещё помнит старые добрые времена DOS, когда мы проводили время, пытаясь выжать более 640Кб для драйверов, программ, резидентов и даже Windows? Такие вещи как QEMM, HIMEM, EMM386.EXE пробуждают у меня теплые воспоминания.

Некоторые из нас даже работали в OS/2, которая выделяла 740Кб для наших DOS-сессий, обеспечивая им вытесняющую многозадачность. Да, я мог запускать несколько DOS-игр одновременно в разных окнах без каких либо проблем. Удивительно, у меня была целая пачка защищённых от сбоев слотов, каждый из которых имел свои 740Кб памяти.

Возвращаясь в сегодняшний день, вы увидите, что Windows CE 5.0 и Windows Mobile 6.x имеют некоторое сходство со своими прадедушками из 80-х и 90-х. 32-битная встраиваемая операционная система, которой мы доверяем управлять нашими Windows телефонами, состоит из пачки слотов, но в отличии от DOS с её 640Кб, ваше приложение получает 32Мб виртуальной памяти. Однако, совершенно как в DOS у вас нет доступа ко всему адресному пространству, потому что другие вещи, такие как системные библиотеки это пространство уже используют.
Недавно я встретил своего хорошего друга Глена Джонса (Glen Jones), который хотел поделиться со мной некоторыми интересными находками. Имейте в виду, дело не только в том, что я считаю Глена и его коллег одними из лучших Compact Framework разарботчиков в мире. Его комманда спроектировала и разработала одно из самых больших и сложных приложений, работающих на Windows Mobile, используя Compact Framework. Как и любые другие компании, которые разрабатывают огромные Windows Mobile приложения, проблемы с нехваткой памяти не обошли и их. Брайан Пайк (Brian Pike), Один из архитекторов "команды мечты" недавно обнаружил, что если держать в памяти пустой exe-файл, а формы, код, ресурсы и данные хранить в отдельных управляемых сборках, то это уменьшает количество расходуемой виртуальной памяти в занимаемом им слоте, одновременно с этим получая возможность использовать память вне слота в рамках 1Гб разделяемой памяти.
Чтобы помочь нагляднее разобраться с этим невероятным открытием, я продемонстрирую две иллюстрации, на которых изображена карта использования памяти управляемым приложением, работающим в двух различных вариантах. Приложение, запущенное на эмуляторах, которые вы видите ниже, отображает использование 32 слотов разделяемой виртуальной памяти.Красным отмечена свободная память, синим — использованная, зеленым — зарезервированная. Слот №1 полон системных библиотек и вы не можете не заметить, что у каждого последующего слота есть небольшая синяя область. Это пространство используется системой и управляемыми библиотеками, что означает невозможность получить свои честные 32 мегабайта.
Слева вы видите Compact Framework приложение StandardExe.exe, запущенное в слоте №14. Это простое управляемое приложение содержит в себе изображение размером 2.25Мб в качестве ресурса и форму, на которой это изображение находится. Если приглядеться, то видно, что 2.25 синих мегабайт находится в нижней части слота №14. Это пространство, занятое нашим exe-файлом.
![]()
Справа находится OptimizedExe.exe, запущенное в слоте №11. Это совершенно пустой exe-файл. Функция Main вызывает метод статического класса в управляемой DLL и всё. В результате мы получаем exe-файл размером 5 килобайт. В управляемой сборке под названием OptimizedDLL.dll у нас находится всё то же 2.25 мегабайтное изображение и форма. Если приглядеться к изображению справа, можно с удивлением обнаружить, что в слоте №11 нет никаких синих участков! А если смотреть ещё пристальнее, то 2.25 мегабайтную сборку невозможно обнаружить где-либо ещё.
Это достаточно здорово и значительно увеличивает наши возможности.Потенциально становится возможным разработать множество игр и приложений, которые ранее не видывали на Windows телефонах.Внимание, вопрос. Как это возможно? Это магия?
Те из вас, кто читал блог Стивена Пратшнера (Steven Pratschner), знают, что Compact Framework размещает управляемые exe и dll в первом гигабайте разделяемой памяти за пределами слота, в котором выполняется ваше приложение, что, безусловно, замечательно. А вот что вы могли и не знать, так это то, что операционная система автоматически блокирует в нижней части слота ровно столько памяти, сколько занимает ваш exe-файл. Таким образом, несмотря на то, что CLR контролирует выполнение приложения и в любовном порыве располагает его в разделяемой памяти, Windows CE отбирает драгоценную порцию памяти, потому как полностью уверена, что именно там и работает наше приложение. А ведь наше приложение управляемое и его там нет! Те из вас, у кого есть огромные управляемые exe-файлы, вы теряете огромный кусок памяти в своем слоте, который можно было бы использовать с гораздо большей пользой! Так что первый урок заключается в том, чтобы сделать то, что сделал Брайан — создать пустой exe-файл в виде заглушки, которая запускает приложение из отдельной управляемой сборки.
Ваш пустой exe-файл может выглядеть следующим образом:
using System;
namespace OptimizedExe
{
static class Program
{
///
/// The main entry point for the application.
///
[MTAThread]
static void Main()
{
OptimizedDLL.StartUp.Main();
}
}
}
Библиотека с приложением:
using System;
using System.Windows.Forms;
namespace OptimizedDLL
{
public class StartUp
{
public static void Main()
{
Application.Run(new Main());
}
}
}
Итак, мы научились обыгрывать Windows CE, играя по её же правилам. Теперь пора поговорить о любопытной ситуации с нашей управляемой сборкой. Если вы читали блог Рида Робинсона (Reed Robinson) про уничтожение монстра в памяти, вы, вероятно, знаете, что библиотеки отъедают память в слотах сверху вних, занимая всё больше и больше, что звучит не очень справедливо. Мы это называем "dll crunch" (скрежет библиотек), потому что свободная память остаётся между библиотеками и exe-файлом. Но у меня есть хорошие новости. Управляемые сборки себя так не ведут! По сути они не только не занимают ни один из слотов, они и ваш основной слот приложения не трогают. Как же это возможно?
Управляемые сборки не являются полноценными dll! CLR обращается с ними, как с обычными файлами и загружает их в гигабайт разделяемой памяти. Для Compact Framework управляемые сборки это просто файлы, полные IL-команд, которые не попадают в слот процесса. Теперь вы понимаете, где находится 2.25Мб изображение, которое мы поместили в OptimizedDLL.dll. Он за границей 32 мегабайтного барьера вашего слота, и тем самым он не расходует драгоценную память!
Так что же, если я последую этому новому способу, будет ли у меня когда-либо расходоваться виртуальная память, или я получил бесплатный обед?
Обед точно не бесплатный, но со скидкой. JIT компилятор выполняется в вашем слоте и подгружает IL-код, необходимый для текущего стека вызовов. Ресурсы, которые не нужно компилировать или выполнять, никогда не будут туда загружены. Куча сборщика мусора (GC Heap) также находится в вашем слоте и именно там зависают выделенные вами объекты. В вашем слоте содержится 64Кб стек для нитей (Thread Stack), которые порождает ваш процесс. Там же находится и куча домена приложения (AppDomain Heap), в которой содержатся представления структур, описанных в ваших сборках.
![]()
Итак, на чем же мы можем сэкономить?
Можно минимизировать ошибочное выделение неиспользуемой операционной системой памяти, следуя вышеописаному паттерну с расположением всего приложения внутри управляемых сборок, которое будет вызываться из пустого приложения-заглушки. Мы потеряем какие-то 5Кб. Спасибо, Брайан!
Размещая управляемые сборки в разделяемой памяти, вы уменьшите вред для других приложений на телефоне, наносимый "библиотечным скрежетом". Это также уменьшит расход памяти в слоте вашего процесса.
Этот новый паттерн разработки управляемых приложений на платформе Windows Mobile является настоящим прорывом в управлении памятью. Присоединяйтесь в мае этого года на Tech Ed в Лос-Анжелесе, чтобы максимально глубоко погрузиться в этот новый способ построения игр и приложений, интенсивно использующих память.
Перевод: Андрей Коновалов
Comments
- Anonymous
May 31, 2009
PingBack from http://microsoft-sharepoint.simplynetdev.com/memmaker-%d0%b4%d0%bb%d1%8f-net-compact-framework/