我试图用C#和AForge库抓住一个框架:
...
using AForge.Video
using AForge.Video.DirectShow
namespace Example
{
class Program
{
private static Bitmap mySnap = null;
static void Main(string[] args)
{
snapByte();
}
private static void snapByte()
{
int Counter = 0;
FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
VideoCaptureDevice videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(videoNewFrame);
videoSource.Start();
do
{
Thread.Sleep(500);
Counter++;
}
while (mySnap == null && Counter < 4);
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource.WaitForStop();
videoSource = null;
}
MemoryStream myStream = new MemoryStream();
mySnap.Save(myStream, ImageFormat.Png);
byte[] snapByteLength = MyStream.ToArray();
int snapLength = snapByteLength.Length;
Console.WriteLine(snapLength);
Console.ReadLine();
myStream.Dispose();
mySnap = null;
snapByte();
}
}
private static void videoNewFrame(object sender, NewFrameEventArgs eventArgs)
{
mySnap = (Bitmap)eventArgs.Frame.Clone();
}
}
}
这是我使用的确切代码,我只是改变了图像字节处理来显示字节长度以简化事情。
我遇到的问题是,每次拍摄快照时,内存将保持在1-2 MB之间。 我正在处理我的所有位图,除了mySnap,我返回null ...我无法处理mySnap,因为它再次使用,我必须声明它全局因为我在snapByte()和newVideoFrame()中使用它 但是因为我重复使用mySnap我不明白为什么它会堆积起来......每次都应该覆盖..
我已经看到了其他答案,但都与图片框有关,答案是在加载新图片前清除图片框。 我相信我通过再次调用mySnap = null来做相同的事情。 但记忆仍在堆积......
谢谢..
答案 0 :(得分:1)
您正在通过snapByte()
方法末尾的snapByte()
无条件调用来创建无限递归。 这会创建一个循环,一旦堆栈空间不足,最终会崩溃;每次你的方法调用自己时,你正在设置一个永远不会被清除的新堆栈帧,因为该方法永远不会返回。这可能需要一段时间才能显示,因为Thread.Sleep()
调用会使您的递归调用受到限制。
此外,在递归调用snapByte()之前未被置零的任何引用将无限期地保留在内存中,因为这些引用在一个永远不会退出的作用域中存活(因为无限递归)并且永远不会由GC回收。
这是videoDevices
集合的情况,但更重要的是snapByteLength
数组实例,它包含您刚刚捕获的位图的副本。我敢打赌这是你内存泄漏的主要原因
避免递归并将其转换为简单的循环应该可以解决您的问题。