我试图用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();
}
}
}这正是im使用的代码,我只是更改了图像字节处理,以显示字节长度来简化事情。
我遇到的问题是,每次拍摄快照时,内存都会保持在1-2 mb之间的位置。除了返回为null的mySnap之外,我正在处理所有位图。我不能处理mySnap,因为它又被使用了,而且我不得不声明它是全局的,因为我在snapByte()和newVideoFrame()中使用了它,但是既然我重用了mySnap,我就不明白它为什么要堆起来了。每次都应该重写..。
我看到了其他答案,但都与picturebox有关,答案是在加载新图像之前清除picturebox。我相信我在这里做同样的事,再次打电话给mySnap=null。但记忆仍在堆积..。
谢谢。。
发布于 2017-06-07 01:07:06
通过在snapByte()方法的末尾无条件调用snapByte()来创建无限递归。--这会创建一个循环,一旦堆栈耗尽空间,就会崩溃;每次您的方法调用自己时,您都会设置一个新的堆栈框架,因为该方法永远不会返回,因此将永远不会被清除。这可能需要一段时间才能显示出来,因为Thread.Sleep()调用将保持递归调用的节流。
此外,在递归调用()之前没有空的任何引用都将无限期地保存在内存中,因为这些引用存在于一个永远不会退出的范围内(因为无限递归),而且GC.将永远不会回收这些引用。
这是videoDevices集合的情况,但更重要的是,对于snapByteLength数组实例,它持有您刚刚捕获的位图的副本。我打赌这是你记忆泄露的主要原因
避免递归并将其转换为简单的循环,这将解决您的问题。
https://stackoverflow.com/questions/44350040
复制相似问题