You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32-CAM调用esp_camera_fb_get()时出现内存泄漏问题求助

ESP32-CAM调用esp_camera_fb_get()时出现内存泄漏问题求助

我仔细看了你的代码和问题描述,发现几个可能导致内存泄漏或栈溢出的关键点,咱们一步步来排查:

1. 全局与局部变量冲突导致的管理混乱

你在全局作用域定义了camera_fb_t *frameBuffer = NULL;,但在loop()里又重新声明了同名的局部变量camera_fb_t *frameBuffer = esp_camera_fb_get();。虽然你在局部代码里做了释放和置空操作,但这个操作只针对局部变量,全局的frameBuffer始终是初始的NULL值。虽然这不一定是内存泄漏的核心原因,但会造成变量管理混乱,建议统一使用全局变量,去掉loop()里的局部声明:

// loop里直接用全局变量,不要重新声明
frameBuffer = esp_camera_fb_get();

2. 内存检查维度的偏差

你当前只打印了栈内存的剩余空间(uxTaskGetStackHighWaterMark),但相机的帧缓冲区是分配在DRAM/PSRAM堆内存中的,栈溢出不一定是相机内存泄漏导致的——有可能是你的loop()任务栈分配太小。建议同时打印堆内存的剩余情况,更准确判断泄漏位置:

// 在loop的打印部分加上这两行
Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

3. 帧缓冲区释放的严谨性优化

虽然你做了if (frameBuffer)的判断再释放,但可以进一步优化代码逻辑,避免潜在的野指针问题:

void loop() {
  frameBuffer = esp_camera_fb_get();

  if (!frameBuffer) {
    Serial.println("Failed to capture frame");
    delay(100);
    return;
  }

  // 可选:打印帧大小,确认缓冲区正常分配
  Serial.printf("Captured frame size: %u bytes\n", frameBuffer->len);

  vTaskDelay(pdMS_TO_TICKS(10));

  // 因为前面已经判断过frameBuffer不为空,直接释放即可
  esp_camera_fb_return(frameBuffer);
  frameBuffer = NULL; // 强制置空,避免后续误操作

  vTaskDelay(pdMS_TO_TICKS(20));

  // 同时检查DRAM和PSRAM的内存完整性
  if (!heap_caps_check_integrity(MALLOC_CAP_8BIT, true)) {
    Serial.println("DRAM Heap integrity check failed \r\n");
  }
  if (!heap_caps_check_integrity(MALLOC_CAP_SPIRAM, true)) {
    Serial.println("PSRAM Heap integrity check failed \r\n");
  }

  // 完整打印内存状态
  Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  Serial.printf("\r\n");
}

4. 相机驱动版本的潜在bug

如果以上调整后仍存在泄漏,很可能是你使用的Arduino-ESP32核心或ESP-IDF版本存在相机驱动的内存泄漏bug——旧版本的OV2640驱动在频繁场景切换、高帧率采集时确实存在这类问题。建议升级到最新的稳定版核心,很多这类问题在新版本中已经被修复。

5. 临时测试方案

可以先尝试降低帧尺寸(比如用FRAMESIZE_QVGA替代FRAMESIZE_QQVGA)或提高JPEG质量值,减少单帧数据量,观察泄漏是否缓解,以此判断是否是大缓冲区分配导致的问题。

备注:内容来源于stack exchange,提问作者Vitaliy Oliynyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:53:11