Accord VideoCaptureDevice事件回调中Bitmap帧持续严重内存泄漏求助
解决Accord VideoCaptureDevice的Bitmap内存泄漏问题
嘿,我太懂这种内存持续暴涨的痛苦了!你遇到的问题大概率是两个容易忽略的点:回调参数里的原始Frame没释放,还有Bitmap的所有权转移逻辑没做好。下面给你一步步拆解修复方案:
1. 先搞懂泄漏的根源
Accord的VideoCaptureDevice在触发NewFrame事件时,会自动创建一个新的Bitmap作为camera_frame_event.Frame——这个Bitmap是设备分配的,回调结束后不会自动回收!如果你每次回调都只处理自己的latest_frame_buffer_Bitmap,却不管这个原始Frame,那内存必然会持续泄漏,而且速度会非常快。
另外,如果你的rotation_filter在处理过程中生成了中间Bitmap但没释放,也会雪上加霜。
2. 修正后的回调代码(带完整资源管理)
直接给你改好的代码,每一步都加了注释:
public static Bitmap latest_frame_buffer_Bitmap = null; private static readonly object frameLock = new object(); // 多线程锁,避免冲突 private static void EVENT_camera_frame(object sender, NewFrameEventArgs camera_frame_event) { // 用using包裹原始Frame,确保不管有没有异常都会被释放 using (Bitmap originalFrame = camera_frame_event.Frame) { Bitmap rotatedFrame = null; try { // 执行旋转过滤,生成新的Bitmap rotatedFrame = rotation_filter.Apply(originalFrame); // 加锁!如果有其他线程在读取latest_frame_buffer_Bitmap,必须避免并发问题 lock (frameLock) { // 先释放旧的Bitmap,?.操作符避免空引用 latest_frame_buffer_Bitmap?.Dispose(); // 把旋转后的Bitmap赋值给全局变量,同时把rotatedFrame置空转移所有权 latest_frame_buffer_Bitmap = rotatedFrame; rotatedFrame = null; } } finally { // 如果rotatedFrame没被赋值(比如中途抛异常),就释放它,避免泄漏 rotatedFrame?.Dispose(); } } }
3. 额外要注意的细节
- 多线程安全:如果你的程序里有其他线程在使用
latest_frame_buffer_Bitmap(比如UI线程显示它),一定要用锁保护,不然可能出现“Bitmap正在被使用时被Dispose”的崩溃,或者读取到半赋值的Bitmap。 - 检查rotation_filter的实现:确保你的旋转过滤器内部没有泄漏Bitmap。比如如果它创建了临时Bitmap,一定要用
using包裹:public Bitmap Apply(Bitmap input) { using (var tempCanvas = new Bitmap(input.Width, input.Height)) { // 这里写你的旋转逻辑,比如用Graphics绘制 using (var g = Graphics.FromImage(tempCanvas)) { g.RotateTransform(90); g.DrawImage(input, 0, 0); } // 返回新的Bitmap,不要返回临时的tempCanvas(因为它会被using释放) return new Bitmap(tempCanvas); } } - 设备停止时的收尾:当你关闭摄像头时,一定要手动清理全局的Bitmap:
// 停止设备后 videoCaptureDevice.Stop(); lock (frameLock) { latest_frame_buffer_Bitmap?.Dispose(); latest_frame_buffer_Bitmap = null; }
为什么之前的代码会爆内存?
你原来的代码只处理了latest_frame_buffer_Bitmap的释放,但每次回调生成的camera_frame_event.Frame都被丢在那里没管——这些Bitmap会一直占着内存,直到GC被迫回收,但GC不会实时处理,所以内存会持续飙升。加上如果旋转过滤器有泄漏,那情况会更严重。
内容的提问来源于stack exchange,提问作者Doug Null
相关产品推荐
相关产品推荐

