Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Управление памятью

From Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Memory Management
Den123
Последнее редактирование: hamishwillee (30 May 2013)

Contents

Введение

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

Ключевые требования Symbian OS для грамотного управления памятью:

  • Использовать минимально необходимый объем RAM
  • Освобождать ресурсы как можно раньше (помните, их объем ограничен)
  • Предусматривать ситуацию возникновения нехватки памяти (out-of-memeory errors) при любой попытке выделения памяти
  • При возникновении ситуации нехватки памяти в процессе выполнения операции необходимо вернуться к стабильному состоянию при этом все выделенные ресурсы должны быть освобождены


Модули управления памятью

  • Стек и куча
  • Сбросы
  • Стек очистки
  • Двухфазное конструирование
  • Утечки памяти
  • Паники
  • Отладка


Стек и куча

  • В стеке:
    • Объекты уничтожаются автоматически
    • Размер стека по умолчанию 8 Кб
  • В куче
    • Для уничтожения объектов необходим явный вызов delete
    • Размер кучи зависит от устройства, но обычно больше 0.5 Мб.


Пример:

TInt i = 0;
CMyObj* obj = new (ELeave) CMyObj;

i - переменная, значение которой хранится в стеке obj - указатель на память, выделенную в куче

Стековые переменные уничтожаются автоматически при выходе программы за пределы видимости. Размер стека по умолчанию 8 Кб, однако его можно изменить, указав значение переменной epocstacksize в файле проекта (.mmp). Замечание: изменение размера стека никак не отражается на работе эмулятора.

Соответственно, динамические объекты (созданные в куче), необходимо уничтожать явно, используя оператор delete, иначе могут возникнуть утечки памяти. Размер динамической памяти в разных устройствах разный, обычно больше 0.5 Мб.


Сбросы

Сброс

  • Сбросы используется вместо C++ исключений, генерация сброса эквивалентна выбрасыванию исключения
  • Сброс может возникнуть при неудачной попытке обращения к ресурсам
  • Сброс проталкивается по стеку вызовов до тех пор, пока не будет перехвачен
  • Используйте перегруженный оператор new: new (ELeave) который приводит к генерации сброса, если не удается выделить требуемый объем памяти
  • Память освобождается стандартным образом с помощью оператора delete
  • Функции, которые могут сгенерировать сброс, должны заканчиваться буквой "L"

Примеры:

Динамическое выделение памяти:

return new (ELeave) TUint8[100];

Генерация сброса:

User::Leave(KErrNotFound); // from e32std.h


Генерация сброса при нехватки памяти:

User::LeaveNoMemory();


Генерация сброса при проверке на NULL:

void CMyClass::SetCallbackL(MNotify* aNotify)
{
User::LeaveIfNull(aNotify);
...

Генерация сброса при возникновении ошибки:

RFs fileServer; // handle to file server
TInt error = fileServer.Connect();
User::LeaveIfError(error);


Стек очистки

Стек очистки

Использование стека очистки:

  • Помещение элементов в стек очистки:
// для указателей - память будет освобождена 
// в случае возникновения сброса
CleanupStack::PushL(ptr);
// для дескрипторов (handles) - дескриптор будет закрыт 
// в случае возникновения сброса
CleanupClosePushL(handle);
  • Удаление элементов из стека очистки:
// удаление элемента на вершине стека
CleanupStack::Pop(pointer);
// удаление и уничтожение элемента на вершине стека
CleanupStack::PopAndDestroy(pointer);

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

Пример:

Если во время выполнения ConstructL() возникнет сброс, self будет уничтожен автоматически:

CMyClass* CMyClass::NewL(TInt aBufSize)
{
CMyClass* self = new (ELeave) CMyClass;
CleanupStack::PushL(self);
self->ConstructL(aBufSize);
CleanupStack::Pop(self);
return self;
}

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

Если функция сохраняет объект с стеке очистки, ее имя должно заканчиваться буквой 'C'.


Двухфазное конструирование

Двухфазное конструирование

Функции NewL() и NewLC().

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


Утечки памяти

Memory leaks

Отладка утечек памяти

This page was last modified on 30 May 2013, at 04:36.
74 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×