This page was last modified 09:00, 7 September 2007.
Управление памятью
From Forum Nokia Wiki
Перевод с английского, оригинальная статья находится здесь.
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().
Эти статические функции включают в себя обе фазы конструирования объекта. Реализация данных функций в классах облегчает использование этих классов, считается правилом хорошего тона.
Утечки памяти
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| we want devcert's with allfiles and TCB! | Santehnik | Symbian Signing, Certification and Security | 90 | 2007-02-16 18:09 |
| Акселерометр | Den123 | Russian Developer Forum - Форум Российских разработчиков | 14 | 2007-12-10 05:45 |
| AknCommonDialogs :: RunSaveDlgLD() -> KERN-EXEC 3 | Den123 | Russian Developer Forum - Форум Российских разработчиков | 7 | 2008-04-10 09:15 |
| Проблема с HTTP Client API | abovesun | Russian Developer Forum - Форум Российских разработчиков | 4 | 2008-07-03 22:00 |
