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

Gstreamer关闭重启RTSP流时内存无法释放的解决求助

问题

我正在开发支持36-64路流的视频墙,遇到了重启流时内存持续增长的问题。应用启动后初始占用内存54MB,启动流后增至约110MB;关闭流时内存未释放,再次启动同一路流后内存增至120MB,以此类推,文件描述符也存在类似问题(怀疑由BUS创建)。

目前我仅将pipeline设置为NULL未执行unref,但取消注释以下代码后,内存消耗仍无变化,尽管函数结束时每个元素及pipeline自身的引用计数均为0:

gst_bus_set_sync_handler(m_videoPipe->bus, nullptr, nullptr, nullptr);
gst_object_unref(m_videoPipe->pipeline);
gst_object_unref(m_videoPipe->bus);
解决方案建议
  • 严格遵循GStreamer完整清理流程:
    1. 先将pipeline状态切换至GST_STATE_NULL,必须同步等待状态变更完成,示例代码:
      gst_element_set_state(m_videoPipe->pipeline, GST_STATE_NULL);
      gst_element_get_state(m_videoPipe->pipeline, nullptr, nullptr, GST_CLOCK_TIME_NONE);
      
    2. 遍历pipeline内所有子元素,逐个释放引用:
      GstIterator *it = gst_bin_iterate_elements(GST_BIN(m_videoPipe->pipeline));
      GstElement *elem;
      while (gst_iterator_next(it, (void**)&elem) == GST_ITERATOR_OK) {
          gst_object_unref(elem);
      }
      gst_iterator_free(it);
      
  • 彻底清理Bus相关资源:
    关闭流前先移除Bus的消息监听,清空未处理消息,再释放Bus:
    gst_bus_remove_watch(m_videoPipe->bus);
    // 清空Bus中剩余消息
    GstMessage *msg;
    while ((msg = gst_bus_pop(m_videoPipe->bus)) != nullptr) {
        gst_message_unref(msg);
    }
    gst_bus_set_sync_handler(m_videoPipe->bus, nullptr, nullptr, nullptr);
    gst_object_unref(m_videoPipe->bus);
    
  • 排查潜在资源泄漏点:
    • 检查代码中是否有未释放的GstBuffer、GstCaps、GstPad等对象,这些小对象累积会导致内存增长;
    • 启用GStreamer内存调试:export GST_DEBUG="GST_MEMORY:5",运行程序查看内存分配日志,定位未释放的内存块;
    • 使用valgrind工具检测内存泄漏,配合GStreamer的--gst-disable-registry-fork选项避免干扰。
  • 解决文件描述符泄漏:
    • 用lsof -p <进程ID>查看打开的文件描述符,确认是否为RTSP连接的socket未关闭;
    • 确保rtspsrc等源元素在状态切换到NULL时完成断开,必要时可以手动调用元素的reset接口(如果有的话)。
  • 检查全局引用残留:
    排查是否有全局变量、回调函数或其他长期存活的对象持有了pipeline或元素的引用,导致gst_object_unref()后引用计数未真正归0。

内容的提问来源于stack exchange,提问作者Deymoss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:52:20