×
Namespaces

Variants
Actions

内存管理

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

文章
dougcn 在 26 Jun 2008 创建
最后由 hamishwillee 在 30 May 2013 编辑

内存管理

Contents

内存管理

Symbian OS的一个基本特征是为具有有限内存容量和可用资源的设备而设计的。因此,它需要非常有效的内存管理。由于缺少资源,任何应用都有可能发生运行时错误: 比如,机器内存用完了或者访问硬件资源失败。这些错误被认为是异常(Exception),不可能通过修改程序阻止它们的发生。所以,程序应当能够在异常发生时恢复。

这样,对于Symbian OS来说,好的内存管理的关键需求如下:

  • 有效编程,你的程序未使用不必要的内存
  • 尽可能早释放资源(记住资源是有限的)
  • 处理内存不够(out-of-memory)错误,事实上你需要对应有内存分配的每一个操作。
  • 当操作中内存不够发生时,返回可接受的稳定的状态,确信你清理了那个操作中分配的一切资源。

内存管理模块

  • 栈和堆
  • 异出(Leave)
  • 清除栈
  • 两阶段构造
  • 内存泄漏
  • Panics
  • 调试

栈和堆

在栈上:

  • 对象被自动删除
  • 缺省大小是 8Kb

在堆上:

  • 对象必须由程序员使用delete删除
  • 大小取决于设备,但一般 > 0.5Mb

例子:

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

这里,i存储在栈上,而obj指向堆内存。

对象在栈上声明时,对象离开其作用范围时被自动删除。缺省的栈大小是8Kb,但可以在项目中(.mmp文件)用epocstacksize声明增大这个值。项目文件中的使用会被后续模块覆盖掉。(注: 使用Emulator时,变更栈大小不起作用。)

作为对照,对象在堆上自动分配时,它需要由程序员使用delete关键字明确删除。若未删除,则发生内存泄漏。在给定设备上,堆的大小会随着可用内存而变化,但应超过0.5Mb。

异出(Leaves)

Leaves

  • 使用Leaves而不是C++ exceptions
  • 当有资源失败时,代码异出”Leaves”
  • 向上传播调用栈知道被处理
  • 概念上,异出(Leaves)等同于抛出一个异常(exception)
  • 如没有足够内存可用,new操作符已被重载以便异出(Leave)
  • 使用 new (ELeave)
  • 正常使用delete释放内存
  • 可能异出(Leave)的函数应以"L"结尾

异出(Leave)例子

  • 动态内存分配:
return new (ELeave) TUint8[100];
  • 引发异出(Leave)
User::Leave(KErrNotFound); // from e32std.h
  • 若无内存则异出(Leaving)
User::LeaveNoMemory();
  • 若为NULL则异出(Leaving)
void CMyClass::SetCallbackL(MNotify* aNotify)
{
User::LeaveIfNull(aNotify);
...
  • 若错误发生则异出(Leaving)
RFs fileServer; // handle to file server
TInt error = fileServer.Connect();
User::LeaveIfError(error);

清除栈

清除栈 非CBase类的清除栈支持

使用清除栈

  • 把条目(items)放到清除栈,用
CleanupStack::PushL(ptr) 用于指针——在异出事件中所指内存将被删除。
 
CleanupClosePushL(handle) 用于句柄——在异出事件中句柄将被关闭。
  • 把条目(items)从清除栈删除,用
CleanupStack::Pop(pointer) 移除顶部条目
 
CleanupStack::PopAndDestroy(pointer) 移除并删除/关闭条目
  • 将对象推入清除栈,当

• 对象被一个本地指针引用,且仅当 • 在该对象生命周期内调用了一个会异出(Leave)的函数

  • 不要把类成员变量推入清除栈

例子:

这里,若ConstructL()异出,self将被自动删除:

CMyClass* CMyClass::NewL(TInt aBufSize)
{
CMyClass* self = new (ELeave) CMyClass;
CleanupStack::PushL(self);
self->ConstructL(aBufSize);
CleanupStack::Pop(self);
return self;
}
  • 当异出不再可能发生时,压入的条目应该从清除栈中弹出
  • 若函数需要在退出前把对象留在清除栈中,则函数名末尾必须有个‘C’。

两阶段构造

Two-phase construction

NewL()和NewLC()

这两个静态函数一气呵成执行两个构造阶段。提供New()或NewLC()为类的一部分使得这个类用起来更容易。NewLC()被典型用在某个函数含有一系列的自动变量(指向堆内存),省得将每一个推入清除栈。

内部链接

This page was last modified on 30 May 2013, at 04:37.
184 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.

×