Mediapipe – 关于对Mediapipe C++ SDK使用不当造成的内存泄漏和内存溢出问题的记录
1 关于对Mediapipe C++ SDK使用不当造成的内存泄漏和内存溢出问题的记录
最近在对我的开源项目:https://github.com/HW140701/GoogleMediapipePackageDll进行性能测试的时候发现,检测一帧视频帧的检测延时很长,一帧大概有20-40ms,所以开始了故障代码排查。
定位到的故障代码如下:
// 1 视频输出结果帧
mediapipe::Packet packet;
if (!m_pVideoPoller->Next(&packet))
{
return absl::InvalidArgumentError("no next packet");
}
if (show_result_image)
{
// 从视频输出获取mediapipe::ImageFrame结果
auto& output_frame = packet.Get<mediapipe::ImageFrame>();
// 转换mediapipe::ImageFrame为cv::Mat
cv::Mat output_frame_mat = mediapipe::formats::MatView(&output_frame);
// 显示cv::Mat结果
cv::cvtColor(output_frame_mat, output_frame_mat, cv::COLOR_RGB2BGR);
cv::Mat dst;
cv::resize(output_frame_mat, dst, cv::Size(output_frame_mat.cols, output_frame_mat.rows));
cv::imshow("MediapipeHolistic", dst);
cv::waitKey(1);
}
上述代码为什么会如此耗时呢?因为获取视频结果帧的耗时很长,性能很差,这一句m_pVideoPoller->Next(&packet)
代码获取结果视频帧耗时很长。在正常情况下我们是不需要结果视频帧输出的,只是需要在显示结果视频的时候再输出,所以为了提升性能,将上述代码修改如下:
// 1 视频输出结果帧
if (show_result_image)
{
mediapipe::Packet packet;
if (!m_pVideoPoller->Next(&packet))
{
return absl::InvalidArgumentError("no next packet");
}
// 从视频输出获取mediapipe::ImageFrame结果
auto& output_frame = packet.Get<mediapipe::ImageFrame>();
// 转换mediapipe::ImageFrame为cv::Mat
cv::Mat output_frame_mat = mediapipe::formats::MatView(&output_frame);
// 显示cv::Mat结果
cv::cvtColor(output_frame_mat, output_frame_mat, cv::COLOR_RGB2BGR);
cv::imshow("MediapipeHolistic", output_frame_mat);
}
修改之后,确实性能有了很大的提升,处理一帧从20-40ms提升到了0ms,但是经过测试,随着处理的视频帧越多,内存一直暴涨到100%,然后程序退出,上述代码出现了严重的内存泄漏和内存溢出问题。
1.2 内存溢出问题的定位与修复
其实最开始出现内存泄漏的问题我也是百思不得骑解,经过两天白用功的试探修改之后还是没有找到问题所在,最后不得不静下心来好好看修改的代码。代码改动的地方就是我们只想要在显示视频帧的时候才去获取结果视频帧,但是我们在初始化模型的时候已经使用m_Graph.AddOutputStreamPoller
将video添加到Mediapipe的图中去了,所以,不管这一帧我们是否设置显示输出结果视频帧,结果都会压入到m_pVideoPoller
的结果队列中去,而我们又设置不显示结果视频,所以没有办法通过m_pVideoPoller->Next(&packet)
拿到packet并释放,导致video的结果视频帧队列越来越大,最后造成内存溢出。
Bingo!
问题解决,修复的代码已经在https://github.com/HW140701/GoogleMediapipePackageDll进行了更新。
1.3 Google Mediapipe对内存溢出问题的解决方案
其实Google在Mediapipe官方文档的Troubleshooting页面也有对内存溢出和内存不足问题进行了解答:https://google.github.io/mediapipe/getting_started/troubleshooting.html#out-of-memory-error
官方文档说内存不足的问题可能是正在运行的MediaPipe图表中累积太多数据包导致的(PS.我也是看到这句话才灵光一现)。而发生累积太多数据包的原因有很多,例如
- (1)图中的一些计算器根本无法跟上来自实时输入流(如摄像机)的数据包的输入速度
- (2)一些计算器正在等待永远不会到达的数据包
对于问题 (1),可能需要丢弃一些较旧的旧数据包以处理较新的数据包。
对于问题 (2),可能是一个输入流由于某种原因缺少数据包。设备或计算器可能配置错误或仅偶尔产生数据包。这可能会导致下游计算器等待许多永远不会到达的数据包,这反过来又会导致数据包在它们的一些输入流上累积。
MediaPipe设置CalculatorGraphConfig::max_queue_size通过限制图表的输入来限制在任何输入流上排队的数据包数量。对于实时输入流,在输入流中排队的数据包数量几乎总是为零或一。如果不是这种情况,您可能会看到以下警告消息:
Resolved a deadlock by increasing max_queue_size of input stream
此外,该设置CalculatorGraphConfig::report_deadlock可以设置图运行失败时显示将死锁错误,以便意识到设置max_queue_size进行内存限制。
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:Mediapipe – 关于对Mediapipe C++ SDK使用不当造成的内存泄漏和内存溢出问题的记录
原文链接:https://www.stubbornhuang.com/2119/
发布于:2022年05月09日 16:56:24
修改于:2023年06月26日 20:12:47
当前分类随机文章推荐
- 姿态估计之Openpose-Body25数据集骨骼关节keypoint标注对应 阅读9292次,点赞5次
- 姿态估计之COCO数据集骨骼关节keypoint标注对应 阅读11723次,点赞5次
- Alphapose - 在Alphapose中使用yolov3-tiny检测器大幅提升检测性能 阅读3088次,点赞0次
- 姿态估计 - COCO-WholeBody数据集骨骼关节keypoint标注对应 阅读3791次,点赞0次
- 姿态估计 - Halpe Full-Body136数据集骨骼关节keypoint标注对应 阅读5145次,点赞2次
- Mediapipe - 全身包含身体、手部、面部所有关键点标注位置对应图 阅读7064次,点赞4次
- Mediapipe – 将Mediapipe HolisticTracking封装成动态链接库dll/so,实现在桌面应用中嵌入全身关节点识别、手势识别、抬手放手检测识别功能 阅读8079次,点赞15次
- 我的开源项目 - 3DPoseEstimation从2D视频中估计人物三维姿势,并生成BVH文件 阅读13223次,点赞32次
- human3.6m : Download(数据集下载) 阅读28625次,点赞40次
- Mediapipe - 使用Mediapipe Holistic识别身体、手、面部全身关节点 阅读7033次,点赞4次
全站随机文章推荐
- C++11 - 使用std::codecvt进行字符编码转换需要注意的时间效率问题 阅读2525次,点赞2次
- 资源分享 - WebGL Gems - Learn How To Create 3D Worlds And Games For Modern Web Browsers, First Edition 英文高清PDF下载 阅读1486次,点赞0次
- TensorRT - onnx_graphsurgeon工具库的安装与API简介 阅读1891次,点赞0次
- 资源分享 - Artificial Intelligence - A Modern Approach , First Edition 英文高清PDF下载 阅读1721次,点赞0次
- 资源分享 - Digital Character Development - Theory and Practice , First Edition 英文高清PDF下载 阅读1723次,点赞0次
- Python - 读取视频为numpy数组以及将numpy数组转换为视频 阅读2919次,点赞0次
- 资源分享 - Mathematics for 3D Game Programming and Computer Graphics, Second Edition 英文高清PDF下载 阅读3031次,点赞0次
- Python - 运算符/ or // or %的含义和区别 阅读2165次,点赞0次
- 资源分享 - GDI+教程(C++中文版 GDI+SDK中文参考手册)PDF下载 阅读3292次,点赞0次
- Docker - 在宿主机与容器之间拷贝文件或者文件夹 阅读75次,点赞0次
评论
169