释放记忆。位图。 [英] Freeing up memory. Bitmap.

查看:131
本文介绍了释放记忆。位图。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨。

我有一个应用程序可以从我的网络摄像头捕获视频并使用队列对其进行补偿。我正在使用aforge.net来捕获视频。我有一个程序占用大量内存的问题。即使缓冲区已满,它仍然继续在内存中进食。我认为它会停在一定的水平并保持在一定范围内,因为队列永远不会超过一定的阈值。



这是我程序中的一些代码:



Hi.
I have an application that captures the video from my webcam and bufferes it using a queue. I am using aforge.net to capture the video. I have a problem with the program taking up a lot of memory. Even when the buffer is full it still continues to eat on the memory. I would think that it would stop at a certain level and stay within that since the queue never grows more than a certain threshold.

Here is some code from my program:

Queue framebuffer = new Queue();

private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {

            
            
            framebuffer.Enqueue(eventArgs.Frame.Clone());
          
            if (seconds > Convert.ToInt16(toolStripTextBoxOptionsDelay.Text))
            {
                

                Bitmap bufferedframe = (Bitmap)framebuffer.Dequeue();
                bufferedframe.RotateFlip(RotateFlipType.RotateNoneFlipX);
                pictureBox.Image = bufferedframe;
                

            }
            if (stopwatch.Elapsed.Seconds > seconds)
            {
               
                Console.WriteLine("Elapsed: " + stopwatch.Elapsed + "  Frames received: " + videoSource.FramesReceived);
                Console.WriteLine("Queue size: " + framebuffer.Count+ "  Frame size: "+eventArgs.Frame.Size);
                
                seconds++;
            }
        }





每次从网络摄像头到达新帧时,都会运行video_NewFrame方法。它需要该帧并将其排入framebuffer。然后在一定的秒数(5秒默认值)后,我开始将缓冲区出列并在pictureBox中显示帧。



我希望内存使用量增长而队列没有被队列化(当然)但是一旦这些秒已经过去并且我开始出列,那么内存使用量应该停止增长,对吧?



有人有解决方案吗?为此或知道发生了什么?我还想知道我是否可以在排队之前缩小位图文件。



谢谢。



Every time a new frame arrives from the webcam the "video_NewFrame" method runs. It takes that frame and queues it in "framebuffer". Then after a certain amount of seconds (5 seconds default value) I start dequeuing the buffer and displaying the frame in a pictureBox.

I expect the memory usage to grow while the queue is not being dequeued (ofcourse) but once those seconds have passed and I start dequeuing then the memory usage should stop growing, right?

Does someone have a solution for this or knows what is going on? I would also like to know if I can shrink the bitmap file before queueing it.

Thank you.

推荐答案

看起来你正在使用 System.Drawing System.Windows.Forms 。您应该始终标记用于UI和图形的库。



查看位图类。它实现了 System.IDisposable 。这意味着,无论你做什么,你最终应该为每个 Bitmap 对象调用 System.IDisposable.Dispose 更长时间使用它。



一些背景



你永远不需要免费的托管内存。它由垃圾收集器回收。这并不意味着托管内存泄漏是不可能的。这是可能的,但它可能是一些设计错误的结果。请看我过去的答案:

Garbage collectotion负责所有内存管理 [ ^ ],

推迟循环中的变量会导致内存泄漏? [ ^ ],

摆脱公共静态的最佳方法列表导致内存不足 [ ^ ],

MDI表单中的内存管理 [ ^ ]。



相比之下,无关 System.IDisposable 机制旨在帮助开发人员保证在通用的基础上始终调用某些清理操作。清理行动本身就是绝对的。它的一个应用是回收非托管资源,这是 Image 和许多其他对象,特别是GDI所需的,还有更多。



最后,您的另一个问题是使用类 PictureBox 。它冗余度很差,应该只用于简化最简单的情况,例如显示一些静态图像。在大多数更复杂的情况下,它只会带来麻烦并使用资源而不会产生任何回报。您应该使用自己的图形渲染,这非常简单。请看我过去的答案:

如何从旧图纸中清除面板 [ ^ ],

在C#中绘制一个矩形 [ ^ ],

在图片框中附加图片 [ ^ ]。







在OP的澄清之后:



上面的最后一段是回合 System.Windows.Forms.PictureBox :不要用它来做任何动态/互动/动画。



我不是指 AForge.Controls.PictureBox (到目前为止我没用过)。



同样,在提问时请务必提供完全合格的类型名称。



-SA
It looks like you are using System.Drawing and System.Windows.Forms. You should always tag the libraries you use for UI and graphics.

Look at the Bitmap class. It implements System.IDisposable. It means that, whatever you do, you should eventually call System.IDisposable.Dispose for each Bitmap object when you no longer use it.

Some background:

You never need to free managed memory. It is reclaimed by a Garbage Collector. It does not mean that managed memory leak is impossible. It is possible, but it can be a result of some design bugs. Please see my past answers:
Garbage collectotion takes care of all the memory management[^],
deferring varirable inside the loop can cuase memory leak?[^],
Best way to get rid of a public static List Causing an Out of Memory[^],
Memory management in MDI forms[^].

In contrast, the unrelated System.IDisposable mechanism is designed to help the developers to guarantee that some clean up action is always called, on a universal basis. The clean up action itself can be absolutely anything. One application of it is reclaiming of unmanaged resources, which is needed for Image and many other objects, in particular, GDI, and a lot more.

Finally, your other problem is using the class PictureBox. It is poorly redundant and should be used only to simplify the simplest cases, such as showing some static image. In most more complex cases, it only presents hassles and use resources giving nothing in return. You should use your own rendering of graphics, which is really simple. Please see my past answers:
How do I clear a panel from old drawing[^],
draw a rectangle in C#[^],
Append a picture within picturebox[^].



After OP''s clarification:

The last paragraph above is about System.Windows.Forms.PictureBox: don''t use it for anything dynamic/interactive/animated.

I did not mean AForge.Controls.PictureBox (which I did not use so far).

Again, please always provide fully-qualified type names when asking questions.

—SA


这篇关于释放记忆。位图。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆