嵌入式系统的内存错误 QNX 软件系统公司
例如,当未分配的内存块损坏时,后续的分配请求期
间通常会出现致命错误。尽管错误可能在下一个分配
请求期间出现,但实际发现的结果取决于一些复杂的
情况,这些情况可能稍后在程序完全不相关的部分引
起一个故障。
检测堆损坏的根源
传统的调试方法很少能找到内存错误的原因,因为这
些错误可能出现在代码库的一个区域,而又表明本身
在另一个区域。例如,在多线程应用程序中,损坏堆
的某个线程可能导致另一个线程出现故障。
出现这种现象的原因是线程以交错方式请求来分配或
释放内存 传统的调试方法通常适用于断点(例如停止
程序执行),以缩小对可疑代码的搜索范围。虽然此
方法可能适用于单线程程序,但通常对多线程执行无
效,因为故障可能出现在难以预测的点上。
多种情况下错误出现在一个区域,而表明本身在另一
个区域。例如,出现以下情况时会导致错误:
? 程序试图释放内存
? 程序试图对释放的内存进行分配
? 内存堆在块释放之前很久就已经损坏
? 后续内存块出现故障
? 使用相邻内存块
这些问题均证明使用高效内存分析工具的重要性。
内存泄漏
如果某个程序分配了内存但随后忘记释放,则会出现
内存泄露。最温和的内存泄露形式是程序占用的内存
超出其实际所需的内存。虽然造成浪费,但如果程序
偶然终止,泄露几乎不会造成危险;大多数现代的操
作系统都可以从中断的进程中恢复内存(包括丢失的
内存)。不过,如果程序导致严重泄
露,或者泄露缓慢但永不终止(嵌入
式系统中可能所需),泄露可能会最
终占用全部内存并造成系统故障。
程序使用内存也可能不是很有效。例
如,某个程序可能为大型数据结构分
配内存或不断扩增动态数据结构,那么就无法长时间
使用该结构。严格来讲,这种情况并不构成内存泄
露,但是可能浪费大量内存,并且可能严重影响系统
性能。
检测内存泄露
良好的内存分析工具报告内存泄露和其他内存错误的
方式相同。图 1 说明了 QNX? Momentics? 工具套件
的分析工具如何显示集成式开发环境 (IDE) 的多种泄
露错误。与其他类型的内存错误一样,开发人员可单
击报告的任意泄露来反向跟踪相关的源代码。
内存分析
内存分析包括捕获关于嵌入式目标的内存相关事件,
将信息导入开发环境,然后使用虚拟化工具找到错误
和确定需要纠正或优化的区域。
内存分析工作流程
开发人员不仅可以通过内存分析找到错误,还能够微调
内存分配,最大程度减少 RAM 使用和确保系统长期可
用性。图 2 展示了从观察开始到优化为止的内存分析过
程。精心设计的内存分析工具可以为内存分析过程的每
一步提供强大的支持:
观察 — 首先,分析工具可以发现运行错误,检测内
存泄露,并显示所有内存分配和解除分配。
纠正 — 接下来,开发人员可以利用该工具跟踪到每
个错误的源代码行。
剖析 — 消除了明显的内存错误和泄漏,开发人员现
在可以随着时间推移分析内存使用,包括平均使用
率、使用峰值和开销。理想情况下,此工具可以显示
长期内存使用,从而立即识别内存分配中的峰值和其
它异常。
图 2:典型的内存分析工作流程。
3