E-ten Club Russia - На лавную --:--

> Утечка памяти в Windows Mobile
2
Опции V
Данная статья перекликается со статьей "Куда уходит память...в Windows Mobile?"

Данное описание базируется на официальной документации по WM хранящейся в MSDN и применимо к следующим компонентам:

- Windows Mobile version 5.0
- Microsoft .NET Compact Framework version 2.0

Напомню, что WM6 базируется на ядре WinCE 5.0. Операционные системы на этом ядре являются 32-х разрядными и имеют много общего в работе подсистемы управления памятью с настольной сситемой Windows XP. Максимальный объем (RAM+ROM+Flash) адресуемого ядром виртуального пространства памяти составляет 4 Гб.

Виртуальное адресное пространство не имеет отношения к объему присутствующей физической памяти!

Это адресное пространство делится между операционной системой и запущенными приложениями. Таким образом



Операционная система резервирует 2 Гб виртуального адресного пространства для работы своего ядра и системных приложений уровня ядра (драйверов, которые работают ниже Hardware Abstration Level (HAL) и на уровне HAL). Область памяти ядра располагается в верхней части виртуальных адресов и обозначена на рисунке как System (kernel mode).

Нижняя половина виртуального адресного пространства отводится по пользовательские программы и данные. Однако, на этом сходство модели памяти WM и ХР заканчивается. В ХР пользовательские приложения могут использоваться все пользовательское пространтсво. В WM пользовательская область разделена на несколько частей.

Самые нижние 64 Мб пользовательского виртуального пространства называются областью приложений (Application space). Эта область используется выполняющимся в данный момент (активным) приложением и для загрузки DLL (динамически загружаемых библиотек) из области ROM (постоянная память). Верхние 1 Гб пользовательской области памяти используются для различных целей и распределяются динамически. Например, из этой области память выделяется для отображаемых на память файлов (memory-mapped files, программисты поймут) и для хранилища объектов (файловый кэш, кэш шрифтов, виджеты пользовательского интерфейса и прочее).

Все пользовательское виртуальное пространство разделено на 64 части по 32 Мб каждая. Это части называются слотами (гнездами).



Два первые слота (0 и 1) используются как адресное пространство приложения. Сюда включается текущий активный процесс (слот 0) и загруженные выполняющиеся DLL (XIP - Executed in place) в слоте 1. Слоты 2-32 занимают остальные пользовательские процессы, которые в данный момент не активны. Слоты с 33 по 62 отводятся под динамическую область памяти. Кроме описанного выше, эта область используется так называемыми "управляющими" приложениями для размещения управляемых ими приложений и их библиотек (Spb Mobile Shell одно из таких "управляющих" приложений).

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



На этом рисунке показан пример использования памяти в области активного процесса. Загруженные в слот 1 DLL становятся доступны всем процессам. Так COREDLL.DLL, которая всегда загружается в верхние адреса первого слота, может использоваться всеми приложениями. В слоте 0 размещается выполняемый код самого приложения, данные приложения, динамически выделяемая память (кучи, стеки). Другим отличием WM от ХР является очень высокая вероятность нехватки доступной памяти, которая практически исключена в настольных системах за счет использования файлов подкачки (свопинга). Кроме того, выделяемые блоки динамической памяти выравниваются на границу 64 Кб блоков. Приложения написанные без учета этого факта очень быстро исчерпывают доступную память. Загружаемые в нулевой слот DLL так же выравниваются на границу 64 Кб. Поэтому программы использующие несколько небольших библиотек вместо одной большой, так же расходуют память впустую.

Таким образом, общий объем памяти процесса ограничен 32 Мб. Если процессу требуется больше динамической памяти, оно может использовать метод отображаемых на память файлов, что позволяет получать память из Large Memory Area. Рекомендуется выделять динамические блоки более 2 Мб именно в виде отображаемых на память файлов.

В общем и целом память мобильных устройств (начиная с WM5) делится на три типа:

- ROM (ПЗУ) постоянная память. Используется для хранения стандартного ПО (системное, дополнительно поставляемое изготовителем устройства).

- RAM (ОЗУ) оперативная память. Используется для размещения кода и данных выполняющихся приложений.

- Persistent storage (постоянное хранилище). По сути, это RAM отображаемая на ROM. В качестве ROM используется FLASH память, которая допускает перезапись информации. Однако такая память имеет на порядки более низкое быстродействие, по сравнению. с RAM. Зато данные в такой памяти не теряются при полном разряде батареи. Специальные методы работы с памятью позволяют приложениям работать, например, со своими конфигурационными данными так, как будто они расположены в ОЗУ, но в то же время избегать их потери.

На этом теоретическую часть можно закончить. Конечно, описание чрезвычайно краткое. Буквально штриховой набросок. Тем не менее, без этого описания не обойтись при переходе к практике. Как Вы знаете, ни один коммуникатор не имеет в сумме 4 Гб памяти (карта памяти не считается). Х800 имеет 64 Мб ОЗУ и 256 Мб ПЗУ (flash, not Ext-ROM!). То есть, виртуальное адресное пространство надо как то втиснуть в реальные рамки. Таким втискивание, по другому называемому отображением, занимается диспетчер памяти процессора. В разных процессорах он реализован по разному, тем более, что и типы реально используемой памяти различны. Но с точки зрения системы, никакой разницы нет. По сути, те самые слоты с помощью адресных регистров отображаются на адреса физической памяти. на следующем рисунке показан пример отображения. Пунктиром обозначена возможная смена содержимого виртуального слота с помощью смены базового адреса физической памяти (без копирования данных). Еще раз отмечу, что полностью механизм работы схем отображения памяти не описываю, так как это весьма нетривиально. Да и не нужно в данном случае. (Кому очень интересно, могут прочитать про процессоры Intel 80х86 тут



Несмотря на фиксированную схему распределения виртуального адресного пространства, физическое пространство распределяется более гибко. По сути, задаются всего две физические границы - доступный объем ОЗУ и доступный объем ПЗУ. Например у меня доступно 171.14 Мб ПЗУ (flash) из 256 и 46.21 Мб ОЗУ из 64. То есть, виртуальные 2 Гб резервируемые системой в результате умещаются в 84.86 Мб ПЗУ и в 17.71 Мб ОЗУ. То есть всего в 102.65 Мб физической памяти. Таким образом получаем объективный ответ на два из часто задаваемых вопросов:

Вопрос: Почему в инструкции написано, что мой коммуникатор имеет 64 Мб ОЗУ и 256 Мб ПЗУ, а в "пуск / настройки / система / память" пишут, что ВСЕГО 171.14 Мб ПЗУ и 46.21 Мб ОЗУ? Куда делась память? Обманывают?

Ответ: Нет, Вас не обманывают. Просто WM для своей работы резервирует определенную часть памяти, которая становится недоступной для обычных приложений. Конкретные цифры резервируемой памяти зависят от конкретного устройства, версии ОС и версии прошивки. В Вашем случае система зарезервировала 84.86 Мб ПЗУ и в 17.71 Мб ОЗУ.

Вопрос: Могу ли я как нибудь изменить размер резервируемой системой части памяти?

Ответ: Да, в некоторых пределах можете. Почитайте, например, тему Только учтите, что это несанкционированное и недокументированное вмешательство в систему. Поэтому Вы все делаете на свой страх и риск.

Теперь коснемся того, как же используется оставшаяся после резервирования физическая память. Понятно, что на эту память надо как то отобразить 2 Гб пользовательской памяти. Жестко разделить пополам, помня о том, что виртуальное пространство разделено на две равные области? Не очень оптимально. Если не будет хватать области процессов, то использовать область динамической памяти иже не получится. Верно и обратное. Поэтому физическая память жестко не делится. И область процессов, и область динамической памяти используют физическую память совместно. Просто для процессов память выделяется с начала физических адресов, а для динамической области с конца (конечно с учетом зарезервированной области).




При этом область процессов расширяется вверх, а динамическая область вниз. То есть, навстречу друг другу. То, что на рисунке обозначено Free и отображается в качестве объема свободной памяти. При выделении/освобождении областей физической памяти возникает ее фрагментация. То есть, внутри, например, области процессов могут появиться свободные блоки памяти. Однако, это не страшно. Вспомним, что память выделяется блоками по 64 Кб. Получается, что дробление свободной памяти на меньшие блоки невозможно. "Сборка мусора" или дефрагментация, теоретически, не требуются. При долгой работе системы без перезагрузок может возникнуть ситуация, когда блоки физической памяти разных областей смешиваются в физической памяти.



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

Общесистемные DLL и процессы совсем не обязательно загружаются в память при старте системы. Например, библиотека времени выполнения языка С++ будет загружена в память автоматически при запуске приложения, которому она потребуется. При завершении такого приложения она может быть удалена из памяти. Тут оказывают влияние два основных фактора:

1. Система подсчета ссылок для DLL. При подключении приложения (процесса) к библиотеке ОС увеличивает на 1 специальный счетчик ссылок, связанный с библиотекой. Когда приложение отключается от библиотеки (например при завершении) счетчик уменьшается на 1. Когда счетчик становится равным 0 библиотека может быть удалена.

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

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

Кэши используются системой для ускорения доступа к тем, или иным, ресурсам. Например, кэш шрифтов содержит фрагменты растеризации глифов TTF шрифтов. Таким образом, потратив определенное время на растеризацию при первом использовании шрифта, впоследствии можно время экономить, так как растеризация больше не потребуется. Но экономия времени требует затрат памяти. Другим примером кэширования является работа с постоянными хранилищами. Я уже говорил, что фактически это отображение ОЗУ на ПЗУ (или наоборот, кому как нравится). Доступ к ПЗУ очень медленный, так что можно сэкономить время за счет дублирования информации из ПЗУ в ОЗУ.

Так как физическая память для двух фиксированных виртуальных областей используется сообща, увеличение размеров кэшей, как и отложенная выгрузка библиотек, сказываются на объеме общей свободной памяти. Таким образом, объем доступной для приложений памяти постепенно уменьшается в процессе работы системы. Однако полностью память не исчерпается. Вы наверно уже заметили, что после СР свободной памяти много, а через некоторое время ее ставится меньше. Постепенно объем свободной памяти стабилизируется. Например, у меня после СР свободно 23.8 Мб ОЗУ, а после нескольких часов работы (естественно с запуском разных приложений) объем стабилизируется на уровне примерно 18 Мб (при отсутствии запущенных приложений). Такое поведение абсолютно нормально. То есть утечки памяти НЕТ. По уже описанным мной выше причинам. Конечно, исключать возможность ошибок в WM полностью нельзя, но вероятность ошибок в коде чрезвычайно мала.

Таким образом, сейчас можно ответить на еще один часто задаваемый вопрос:

Куда утекает память? Когда это кончится?

Ответ Память никуда не утекает. Уменьшение объема свободной памяти связано с тем, что физическая память используется совместно и для запуска приложений, и в качестве динамической памяти приложений, и для загрузки динамических библиотек, и для различного вида кэшей. Если приложения не сворачиваются, а закрываются, то объем свободной памяти постепенно стабилизируется (уменьшение составит около 25% первоначального объема свободной памяти). Зато быстродействие коммуникатора будет выше за счет такого использования памяти.

Если память кончается в процессе работы приложения, то такое приложение запрашивает для себя динамическую память без ее освобождения. Например, гипотетический IM (Instant Messenger) хранит в памяти историю сообщений, при этом старые сообщения не удаляются. В данной ситуации ни Microsoft, ни E-Ten не виноваты. Вините разработчика такого приложения. Естественно, когда такое приложение займет значительный объем памяти, другие приложения начнут работать не корректно, или вообще откажутся запускаться.

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


Спасибо Systo за предоставленную информацию.

Обновлено: 12.8.2008, 20:08 от ViP®    Создано: 12.8.2008, 20:00 от ViP®    Изменений: 3    Просмотров: 10 370
Распечатать  Скачать версию MSWord  Скачать txt версию
Тема обсуждения статьи

> Навигация
История
RSS Нет изменений
Статистика
Создано 228 статей в 93 разделах.

Изменено 513 edits have been made and our articles have been viewed 1 265 080 times
- Текстовая версия | SEO by MinervaSEO © Icelabz.net Сейчас: 22.8.2017, 6:30
Rambler's Top100 Рейтинг@Mail.ru Яндекс цитирования Rambler's Top100   Internet Map
 
admin@etenclub.ru
E-ten Club Russia 2007-2014.
Design & Code by DDK.