1. 内存泄漏基础

各位同学好,我是老张。在嵌入式领域摸爬滚打了十几年,今天咱们来聊聊MTK8676平台上一个让人头疼的问题——内存泄漏。说实话,我见过太多项目因为这个看似不起眼的问题,最后搞得焦头烂额。

1.1 什么是内存泄漏

内存泄漏,说白了就是程序向系统申请了一块内存,用完之后忘了还回去。你想想看,就像你借了图书馆的书,看完不还,时间长了图书馆的书架就空了,别人想借也借不到。

在C/C++开发中,我们经常用malloc、new来申请内存。但问题是,很多人只记得申请,不记得释放。我见过最夸张的一个案例,有个同事写了个循环,每次循环都new一个对象,但从来没delete过。跑了一个晚上,系统直接挂了。

典型的内存泄漏场景:

  • 动态分配的内存没有释放
  • 容器类对象(如std::vector)不断增长
  • 回调函数中分配的内存忘记释放
  • 异常处理路径中遗漏了释放操作

来看个简单的例子:

// 典型的内存泄漏代码
void process_data() {
    char* buffer = (char*)malloc(1024);
    // 处理数据...
    // 忘记调用 free(buffer);
    return;  // buffer 泄漏了!
}

嗯,这里要注意。很多人觉得就1024字节,泄漏就泄漏了。但在嵌入式系统里,内存总共就那么点,积少成多,迟早出事。

1.2 内存泄漏的危害

内存泄漏的危害,我总结为三个字:慢、卡、死。

危害等级 表现 实际影响
轻度 系统响应变慢 应用启动时间增加,界面卡顿
中度 功能异常 音视频不同步,导航卡死
重度 系统崩溃 黑屏重启,数据丢失

我在项目中遇到过最惨的一次,是车载导航系统在连续运行72小时后突然死机。查了三天,最后发现是一个地图渲染模块每次刷新都泄漏了4KB内存。72小时下来,内存被吃光了。

避坑指南:我曾经以为内存泄漏只影响长时间运行的系统。直到有一次,一个短时间运行的功能测试,因为频繁调用泄漏代码,5分钟内就把内存耗尽了。所以,别小看任何一次泄漏。

为什么会这样?因为嵌入式系统的内存资源是有限的。MTK8676平台虽然性能不错,但它的内存分配策略和PC完全不同。你想想看,PC上泄漏个几百MB可能还能撑一会儿,但在车机上,几十MB的泄漏就足以让系统崩溃。

1.3 MTK8676平台内存架构概览

MTK8676是联发科面向智能座舱的高性能芯片。它的内存架构,我个人觉得设计得挺有意思。

先看整体架构:

MTK8676 内存架构简图
┌─────────────────────────────────────┐
│          CPU Cluster                 │
│  ┌──────┐ ┌──────┐ ┌──────┐        │
│  │ A78  │ │ A78  │ │ A55  │        │
│  └──────┘ └──────┘ └──────┘        │
├─────────────────────────────────────┤
│          Memory Controller           │
├─────────────────────────────────────┤
│  ┌──────────┐  ┌──────────────────┐ │
│  │   DDR    │  │   Internal SRAM  │ │
│  │ (4-8GB)  │  │   (几MB级别)     │ │
│  └──────────┘  └──────────────────┘ │
└─────────────────────────────────────┘

这个平台有几个关键特点:

  • DDR内存:主内存,4-8GB,用于运行应用和系统服务
  • 内部SRAM:极少量,用于实时性要求高的场景
  • 共享内存:用于多核通信和多媒体处理

个人经验:我建议你在做内存泄漏检测时,重点关注DDR区域。因为大部分应用代码都跑在这里,泄漏也主要发生在这里。内部SRAM虽然小,但通常由底层驱动管理,出问题的概率低很多。

MTK8676的内存管理还有个特点——它用了CMA(Contiguous Memory Allocator)机制。说白了,就是给多媒体模块预留了一大块连续内存。这块内存如果泄漏了,后果更严重,因为其他模块想用也用不了。

我记得有一次排查一个视频播放卡顿的问题,查来查去发现是CMA区域被某个驱动泄漏了30%的空间。视频解码器申请不到连续内存,只能降级处理,画面自然就卡了。

所以,在MTK8676上做内存泄漏检测,不能只看总量。你得知道内存分了几块,每块是干什么用的,泄漏发生在哪一块。这样才能精准定位问题。

好了,这一章的基础知识就讲到这里。下一章我们开始实战,我会带大家用工具在MTK8676上实际检测内存泄漏。到时候你们会发现,理论是一回事,动手又是另一回事。