Symbian内存管理(转)

news/2024/7/20 13:47:52 标签: 内存管理, c/c++, 操作系统

Why Memory Management

Symbian OS本身就是为内存和资源受限的设备开发的,应用程序运行过程中很可能碰到内存用光,或者硬件资源不可用的情况。而这种exceptions是通过修改程序无法解决的,所以遵守以下几条:

  • 尽量不要使用不必要的RAM
  • 尽早释放资源,如文件server等
  • 当你每次申请内存时,都须准备处理out-of-memory错误
  • 当 out-of-memory错误发生时,返回到一个stable的状态,并释放所有期间申请到的资源

Stack and Heap

Stack:默认大小8kb,自动删除,如 TInt i = 0;

Heap :至少0.5Mb,由程序员手动删除,如 CMyObj* obj = new (ELeave) CMyObj;

Leaves

首先介绍Conventional C++ Memory Management,在Symbian看来,这是非常低效率的。

  • NULL Pointer Checking if ((myObj = new CMyObj( ) ) == NULL) { //Error Handling }
  • ANSI C++ Exeption Handling try { //throw an Exception } catch (int e) { //Error Handling }

Symbian中推荐采用Leave,如果内存或者资源不能分配到,这个代码就会Leave,沿着Call Stack,直到操作系统或者在某个函数中被Handle掉。

所有可能Leave的函数最好以L结尾,保证该函数的用户知道这个函数可能Leave。

Leave的例子:

  • 动态内存分配: return new (ELeave) TUint8[1000];
  • 产生一个Leave:User::Leave(KErrNotFound);
  • 内存不足时Leave:User::LeaveNoMemory();
  • NULL的时候Leave:User::LeaveIfNull(aNotify);
  • 当发生错误时Leave:RFs fs; TInt err = fs.Connect(); User::LeaveIfError(err);

处理Leave:

操作系统有默认的处理Leave的方式:

  • 在程序启动过程中:直接关闭应用程序。
  • 应用程序启动后:显示一个错误消息。

开发者可以通过trap装置来处理Leave。TRAP(_r, _s)和TRAPD(_r, _s),其中:

  • _r:是一个TInt类型的leave code,默认值为TErrNone。
  • _s:一系列可能Leave的C++ Statements。

TRAPD(err, DoFunctionL());
if (err != KErrNone)
{ //Error Handling }
else
{ //Everything is well }

The Cleanup Stack

cleanup stack用于存储在leave发生后需要deallocating的局部变量(指针)。即:当一个函数leave了,所有在cleanup stack上的对象会被全部删除掉。

Cleanup Stack的使用方法:

CleanupStack::PushL(ptr) :当发生leave时所有内存都会被释放
CleanupClosePushL(handle):当发生leave时这个句柄(handler)会被关闭

CleanupStack::Pop(pointer):第一个元素出栈
CleanupStack::PopAndDestroy(pointer):第一个元素出栈并释放内存

如果一个函数可能leave,检查一下两种情况:

  • 如果leave了,是否所有在堆(heap)上的元素都在cleanup stack中了
  • 如果没有leave,你是否自己恰当地将他cleanup了

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

如果某个函数会在cleanup stack上留下一个对象,那么他必须以C结尾。

Two Phase Construction

C++构造函数一定不能leave。所有内存和资源的分配应该在第二阶段构造函数ConstructL( )中完成。

编码指南,所有用户定义的C类必须:

  • 定义NewL和NewLC函数为public static
  • 定义ConstructL和C++ Constructor为private

Best Practise

Construction的规则:

  • 默认的C++构造函数中不能含有可能leave的代码
  • 可能发生leave的函数必须在ConstructL中被调用
  • 如果基类也有ConstructL,必须首先调用,不要忘了explicit scoping

Destruction的规则:

  • C类必须在析构函数中删除它自己所包含的对象
  • 在删除一个对象后,把它的指针设为NULL
  • 不要删除不是本类所拥有的对象
  • 在reallocation前首先删除对象,并且将其指针设为NULL

Further Discussion:

  • Preserve Stack Memory:每个进程只有8K,以引用的方式传递参数,大的对象放在堆上
  • Preallocation vs last moment allocation:一般的原则是只在使用前分配资源并且在使用后马上释放。但是 preallocation的好处是节约处理时间,并且在没有内存的情况下照常运行(资源已经分配到了)
  • where to put trap harness:最基本的情况是依靠GUI应用程序的框架。根据应用的不同,可以自定义粒度。
  • Error Code Returns vs. leaving functions:在执行某个处理前检测是否会出现问题,如下代码:

User::LeaveIfError(fs.Connect());

Memory Leaks

如果你的程序有内存泄露,在模拟器上关闭时会crash。尽早发现并解决你的内存泄露,因为你可以追查到你可能导致内存泄露的代码改动。如果实在找不到,可用下面方法:

Heap Balance Checking:

  • _UHEAP_MARK
  • _UHEAP_MARKEND

用上述这两个宏放在你要检查的代码的开头和结尾,如果发生panic,则说明这段代码中发生了内存泄露。可以嵌套使用。

Panics

Panic是一个未经处理的exception,暗示着一个无法解决的错误。

一般程序有以下三类错误:

  • 程序错误:如引用一个超过数组范围的元素
  • 环境错误:内存、磁盘空间不够,或缺少其他资源等
  • 用户错误:输入错误数据
可以使用trap和cleanup stack技术来解决环境和用户错误,但是对于第一类的程序错误,我们无法恢复,最好是使用User::Panic()函数,它带有两个参数,第一个是string,第二个是Tint。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126316/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-126316/


http://www.niftyadmin.cn/n/1444307.html

相关文章

mediasoup 源码分析(十三) 丢包重传 webrtc nack 机制

一、丢包介绍 由于webrtc所用的rtp协议底层是基于udp传输,所以并不能保证数据的可靠性。在发生丢包时,为了保证音视频的质量需要进行重传,而 nack机制就是用来处理重传逻辑的,需要注意一点由于udp本身是无序的,所以在进行丢包重传时要做一定的特殊处理。 二、nack 报文介…

使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发

2019独角兽企业重金招聘Python工程师标准>>> 概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解。可加群获取原始文档。 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现。通过本篇教…

obs-studio 二次封装 (四)obs 音视频采集到推流大体流程图

一、obs 大体流程 由于obs整个项目代码量很大,刚开始接触时不知道从何着手。所以,整理出一份简单的流程图,大家后面做二次封装时可以对照这个流程图。 当然,每个过程都有一些细节需要做。比如,如何遍历音视频列表、如何调整编码器参数等等。流程图会列出每个步骤的关键函…

【索引】Fundamentals

AOAPC I: Beginning Algorithm Contests -- Training Guide (Rujia Liu) Chapter 5. Graph Theory:: Fundamentals ExamplesExamples:BeginnerExamples:IntermediateExamples:Advanced

电影“防火墙” 引发的黑客攻击迅雷(转)

最近刚出了一部新片“防火墙”,这是一部有关黑客的电影,所谓“外行看热闹,内行看门道”,从剧中我们可能看到一项黑客技术的威力——那就是社会工程学!由于“防火墙”的启发,我对下载软件“迅雷”进行分析&a…

uva 10319 - Manhattan(2 sat)

题目链接&#xff1a;uva 10319 - Manhattan 对于每对点&#xff0c;(r1&c2) || (r2&c1)&#xff0c;根据分配率拆成4条关系&#xff0c;然后做一遍2 sat。 #include <cstdio> #include <cstring> #include <vector> #include <algorithm>usin…

licode源码分析(一)WebRtcConnection 创建

1、WebRtcConnection 介绍 WebRtcConnection是进行webrtc协议交互的主要类,如:sdp解析与交互、Candidate信息交互、stream流管理、srtp包处理。 2、WebRtcConnection创建逻辑 代码见:licode\erizo_controller\erizoJS\models\Connection.js 的 _createWrtc()函数 wrtc =…

Spring Boot使用HandlerInterceptorAdapter和WebMvcConfigurerAdapter实现原始的登录验证

HandlerInterceptorAdapter的介绍&#xff1a;http://www.cnblogs.com/EasonJim/p/7704740.html&#xff0c;相当于一个Filter拦截器&#xff0c;但是这个颗粒度更细&#xff0c;能使用Spring的Autowired注入。 WebMvcConfigurerAdapter的介绍&#xff1a;http://www.cnblogs.c…