嵌入式系统设计中消除内存丢失的策略[转帖].docVIP

嵌入式系统设计中消除内存丢失的策略[转帖].doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
嵌入式系统设计中消除内存丢失的策略[转帖] 在嵌入式系统设计过程中,许多软件工程师受困于动态内存管理。本文介绍一种将堆栈中的内存碎片降至最少的解决方案,其中讲到了内存碎片和内存丢失的区别,以及一种在编程中有利于检测并消除内存丢失的策略。 标准C库函数malloc()和free()可在任意的时间段中,为应用分配任意大小的内存块。随着内存块的使用和释放,在整个内存区域中,分配给堆栈的存储区将混杂着许多正在使用或已经释放的存储块,而未被使用的任何小块内存区将变得无法使用。例如,某个应用要求堆栈分配30字节,如果堆栈中只有20个长度为3字节的小存储块(总共为60字节),那么堆栈仍然无法为该应用分配内存,因为所需的30字节必须是连续的。 在执行时间较长的程序中,内存碎片可能导致系统的内存枯竭,尽管分配的内存总量并未超出总的可用内存总数。内存碎片的数量取决于堆栈的实现策略。大多数程序员均采用由编译器提供的malloc()和free()函数创建的堆栈,因此内存碎片就不受程序员的控制。 内存丢失是应用程序的缺陷,更具体地,内存丢失是一块已经分配但永远不会被释放的内存区。如果所有指向内存块的指针超出界限或者指向其他的区域,那么应用程序将永远不能释放那块内存区。对于将会在某时刻退出的桌面应用程序,较小的内存丢失还可以承受,因为退出进程将把占用的所有内存返还给操作系统。但对于长时间运行的嵌入式系统,则通常需要确保绝对没有内存丢失。 避免内存丢失不是轻而易举的,为了确保所有分配的内存都在随后释放,必须建立一套明确的规则,以确定哪个应用占用了内存。为跟踪内存,可采用类、指针数组或链表。由于在动态内存分配中,程序员无法预先知道在给定时间内需要分配多少数据块,因此通常需要采用链表结构。 例如,假定一个任务正在接收来自通信信道的消息,任务将为消息分配空间,而该空间在消息得到完整的处理之前不会被释放。因为消息有可能不会按照接收的顺序进行处理,因此一些消息存在的时间将比其他消息更长。所有挂起的消息存在于一个列表中,列表的长度取决于任意给定时间内进行处理的消息数目。嵌入式系统必须将消息转发至另外的设备,而且消息在收到传送确认之前不能被删除。由于消息将传送至许多不同的目的地,而且某些目的地可能存在一些导致重传的故障,因此不能以先入先出方式处理这些消息。 在上述问题中,动态内存管理对RAM的利用效率高于预定义缓存管理。当内存不再被消息队列使用时,就能被其他队列或完全不同的程序部分使用。 当多个指针同时指向某个特定的内存块时,通常还会产生另一个特殊问题。如果第一个实体(entity)占有内存并希望释放该内存,那么必须考虑是否还有其他指针指向该区域。如果存在,那么随着第一个实体释放内存,其他的指针将成为悬挂指针(dangling pointer),即该指针指向的空间不再有效。当使用悬挂指针时,或许仍然可以得到正确的数据,但这些内存终将被重新使用(通过另一个malloc()调用),从而导致在悬挂指针和该内存的新使用者之间出现不期望的相互影响。 悬挂指针与内存丢失刚好相反。如果没有释放内存,就可能导致内存丢失;而如果释放了那些并不准备释放的内存则将产生悬挂指针。 内存丢失在许多方面与竞争条件非常相似。内存丢失引发的性能失常完全不同于程序错误,因此,这些问题很难通过调试器对代码进行单步调试加以解决。对于内存丢失和竞争条件,代码检查有时能比采用任何技术解决方案更快地找到问题所在。 添加调试代码并生成输出通常比源代码调试器更为有效,但在某些竞争条件下,则有可能改变代码的执行特性,从而掩盖了问题。在内存丢失中,添加调试代码可改变内存配置,这意味着悬挂指针故障可能具有不同的执行特性。另一缺陷在于,如果调试代码消耗了内存,那么调试版将比产品版更快地耗尽RAM,内存丢失就是内存丢失,而不管这些调试代码的副作用如何,都应当可被检测。 驱动自动碎片收集 Java具有对无用存储单元进行碎片收集(garbage collection)的自动内存管理机制,因此Java程序员无须担心内存分配的释放。如果以前曾用过Java进行编程,那么与其他编程语言相比,无疑会对Java跟踪内存所需的时间留下深刻的印象。 在Java中,只需牺牲运行时间即可换来编程的简化,因为手工管理内存可以得到更为有效的实现方法。但当程序变得越来越大,手工管理就变得无能为力了。虽然好的手工管理通常能使堆栈的总长度降至最小,但这并不总是轻而易举的。在那些通常由数十名程序员完成的大型程序中,人为错误将引入足以降低性能等级的大量内存丢失,这时就需要自动碎片收集解决方案。 在对无用存储单元进行自动碎片收集过程中,一个优秀的程序员或许做得远比自动碎片收集器出色,但在需要众多程序员参与的大型项目中,则几乎不可能找到

文档评论(0)

天马行空 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档