BREW Heap 管理 -读书笔记

  原文出处:http://www.docin.com/p-36672037.html 

 

BREW通过IHEAP 接口可以管理BREW 堆栈。

IHeap接口及函数

OEM_GetinitHeapBytes() (OEMHeap.c中)可以设置用户使用堆栈的大小和位置

BREW开放IHeap接口函数,用于动态获取、释放内存和获取堆栈信息。BREW同时提供了一些助手函数,如MALLOC()等用于简化内存操作。OEM层也可以在静态应用开发中使用使用OEM_Malloc()、OEM_Free()等函数。

BREW 堆栈的管理

为了防止BREW应用引发内存泄露,BREW对BREW 应用分配的内存进行了跟踪。BREW为每个在BREW堆栈中分配的内存都维护了一个information block,称为堆栈节点。堆栈节点是一个32bit的ID,处于分配的内存地址的前4个字节中。比如,通过MALLOC()函数成功分配内存后返回的地址的前4个字节。

动态应用通过MALLOC()、REALLOC()或IHEAP_Malloc()、IHeap_Realloc()来分配内存。默认情况下,BREW会使用BREW app 模块上下文的32bit ID来标记分配的内存节点。即BREW用于跟踪应用内存的32bit ID事实上是每个module的ID,这意味着来自同一个module的两个应用可以拥有相同的32bit ID。

对于静态应用,可以使用MALLOC()、REALLOC()或者IHEAP_Malloc()、IHEAP_Realloc(),也可以使用OEM_Malloc()、OEM_Realloc()和sys_malloc()和sys_realloc()函数。在这些调用中,内存通常标记在system context 下。静态应用也可以在调用MALLOC()、REALLOC()或者IHEAP_Malloc()、IHEAP_Realloc()函数前将上下文改为system context,这会改变默认行为并导致分配的内存标记在system context下。

当一个应用退出时,BREW会在堆栈中查找标记为该应用的32bit ID的堆栈节点。一旦找到,BREW会调用OEMOS_BreakPoint()函数报告内存泄露然后自动释放相关分配的内存。BREW会在一个module中所有的应用都退出时才执行内存泄露检测。当在模拟器中发现内存泄露时,会直接报错,而在目标设备中,泄露会被清理回收。

BREW Extensions中BREW Heap的用法

当BREW应用创建一个extension实例时,将实例化该extension的IModule。在实例化extension的IModule时分配的内存与extension的module context相关联,分配的内存用extension的module context的32bit ID值进行标记。

当实例化IModule后,为该extension实例分配的任何其他内存都与BREW应用调用程序的module context相关,这些内存被标记为BREW 应用的32bit ID 值而不是extension的module context ID。

在system context中分配内存

当一个静态extension的接口只有一个实例并且被其他应用共享时,或者当它开放了一些底层资源时,比如解析一段buffer中的信息,该类实例的内存应当在system context中进行分配。如果extension是在system content 中分配的,那么在析构时应该注意确保资源的释放以免内存泄露。这可以通过增加引用并在AEE_Exit()时清除引用计数来强制释放。你可以通过注册一个系统回调,以便在AEE_Exit完成时强制释放内存并重置指针或全局变量。

如果一个extension对外提供了service,每个调用的应用都需要设置自己的数据,在这用情况下,最好的方式是在应用的module context下分配内存,并在每次调用MYExtension_New()时分配一次。如果可以的话,在应用中分配内存并只是将内存传入使用是最好的方式。如果在应用中需要获取内存的大小,可以提供一个计算方法的函数或在函数中添加一个输入输出参数。为了避免资源泄漏,最好通过使用AEE_LinkSysObject()函数将这些实例与正在执行的应用相关联来确保当该应用所属的module释放时执行析构函数。

检测内存泄露

BREW应用引发的内存泄露可以在应用所属的module释放时被检测出来。

可以通过在OEMOS_Breakpoint()中设置断点来检测。

AEEAppLeak结构中包含了内存泄露的详细信息。

AEE_GetMemGroupName(pal-dwMemGroup, szBuff, sizeof(szBuff));可以获知所属的应用。

 

AEEAppLeak中的pBuffer指向了泄露的内存,因此,你可以通过dump该buffer来辨识。buffer可以方便的通过在data.dump中

查找到。

低内存提示

在BREW 3.1中,BREW应用可以注册低内存通知并定制释放内存方法。当BREW 应用在调用MALLOC失败并且没有足够内存时,就会触发低内存通知。

应用可以通过调用ISHELL_OnLowRam()或者ISHELL_RegisterSystemCallback()并把nSCBType设为AEE_SCB_LOW_RAM来注册一个当系统达到低内存条件时触发的回调函数。这允许应用进行相应的内存处理。

应用也可以通过调用ISHELL_OnLowRamCritical()或者ISHELL_RegisterSystemCallback()并把nSCBType设为AEE_SCB_LOW_RAM_CRITICAL来注册一个回调函数,以便在系统达到低内存条件并且使用AEE_SCB_LOW_RAM回调无法获取足够的RAM时能够释放更多的内存。调用应用必须属于AEEGROUPID_LOW_RAM以便成功注册该回调。

一旦BREW应用注册接收低内存通知,BREW会首先将低内存通知发给注册该通知的应用,该应用接收到通知后会释放更多可用内存,在这个通知之后,BREW会再次检测可用内存,如果所需的内存仍然不够,BREW 会发出critical low RAM notification给那些注册了改通知的应用。

如果没有应用注册了低内存或紧急低内存通知,或者发出通知后释放的内存仍然不够,BREW会尝试通过卸载application stack中的应用来释放自己的内存。

BREW通过自己的方式释放位于current top visible应用下的第一个挂起的应用。它从内存中卸载该应用(该应用会接收到EVT_APP_STOP事件),但是,该应用在应用历史堆栈中的实体却没有删除,这就允许BREW在当前激活应用退出时自动重启该应用。

卸载了一个应用之后,BREW会检测可用内存是否满足MALLOC请求,如果满足,则MALLOC返回成功,如果仍然没有足够的内存,BREW会继续卸载堆栈中的下一个应用,直到它获取足够的可用内存来满足MALLOC请求。如果卸载了所有应用(不包括当前激活应用),而内存仍然不足,BREW会在MALLOC中返回NULL。

在BREW释放内存的整个过程中,并不会牵涉到后台应用。当top visible应用退出时,BREW重新加载挂起的应用并且向该应用发出resume事件。resume的应用可以获取其在应用中保持的任何数据,因为BREW在a卸载该应用的时候依旧保留了改应用的AppHistory entry。

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值