【问题标题】:C# BufferedGraphics Memory LeakC# BufferedGraphics 内存泄漏
【发布时间】:2014-11-01 19:32:23
【问题描述】:

我的代码格式如下:

while (Globals.Running)
{
    if ((Form.Visible == false) || (Form.ContainsFocus == false) || (Form.Enabled == false))
    {
        Threading.Thread.Sleep(100);
    }
    else
    {
        Update();
        Draw();
    }

    Application.DoEvents();
}

当我在任务管理器中查看进程时,我看到消耗的内存每秒增加 8K。

如果我注释掉Draw() 调用,内存是稳定的。因此,内存在Draw 内部泄漏。该方法如下所示:

private static void Draw()
{
    BufferedGraphics.Graphics.Clear(Color.CornflowerBlue);
    //Engine.Draw(BufferedGraphics.Graphics);
    BufferedGraphics.Render();
    ++FPS;
}

所以,即使我没有画任何东西,记忆也会丢失。如果我注释掉.Clear 行,它仍然会泄漏。如果我注释掉 .Render 行,它仍然会泄漏。如果我将这两个都注释掉,它就会停止泄漏。

BufferedGraphics 在构造函数中初始化如下:

BufferedGraphics = BufferedGraphicsContext.Allocate(Graphics.FromHwnd(Form.Handle), Form.ClientRectangle);

所以,我的问题是,为什么不渲染/清除图形上下文会泄漏内存?或者这里还有其他什么在起作用?

【问题讨论】:

  • 您很可能只是不了解 .NET 的内存管理是如何工作的。 .NET 使用的垃圾收集器只偶尔收集一次内存——除非“泄漏”的内存超过 10-20 MiB,否则你可能不会遇到问题。有几件事可能会在这里和那里生成一些对象,从而导致内存使用量有所增加 - 即使“游戏循环”中的 Application.DoEvents 也不是最佳的。如果您正在执行实时渲染,那么看看 SharpDX/SlimDX 之类的图形库可能是值得的。
  • 我明白了。我研究了 SlimDX,但由于我不需要任何密集的东西,只需要一些位图和一些文本,我认为这可以做到。我想我会像 PieterSchool 和 DJ KRAZE 所说的那样改成Dispatcher.Invoke
  • 好吧,Dispatcher.Invoke 仍然有内存开销。换个角度想一想——你真的想要以固定的 FPS 进行实时渲染,还是想要基于事件的渲染?如果是实时的,请保持循环不变,这很好。如果基于事件,Winforms 和 WPF 都可以很好地工作,不需要仅仅为了它而使用游戏循环。
  • 是的...起初我以为我需要实时,但现在...你说得对,我真的不需要它。感谢大家的帮助:)

标签: c# memory-leaks gdi


【解决方案1】:

不要使用 application.doEvents!使用调度程序在不同线程上操作时更新 UI,这将防止 UI 阻塞并且更改不会泄漏内存

示例: Dispatcher.Invoke to update UI Control

【讨论】:

  • 我同意不要使用Application.DoEvents(); 这不是一个好习惯
  • 您没有深入了解它 - 这是一个明显的游戏循环,而不是在 Winforms 中进行协作多任务的尝试。 Application.DoEvents() 循环已经被使用了一段时间。它们不是制作游戏循环的最佳方式,但也不是那么糟糕。
  • Application.DoEvents() 被阻塞。当某件事以某种方式完成了很长一段时间后,它并不是一个好的选择。
  • 但是你没有抓住重点——Invoke 根本没有帮助。事实上,这是一种扼杀任何获得良好性能机会的好方法——它会导致大量不必要的分配,并且 OP 很可能甚至没有任何要更新的控件。我可能是错的,但我认为他只是在 GDI+ 中制作游戏——除非他确实将自定义渲染与实际的 winforms/WPF 控件结合起来,否则Invoke 比没用还糟糕。
猜你喜欢
  • 2016-01-27
  • 2010-11-11
  • 2017-02-18
  • 1970-01-01
  • 2015-11-19
  • 2020-03-31
  • 2016-03-15
  • 2015-07-25
  • 2018-01-03
相关资源
最近更新 更多