【问题标题】:Memory leak in my SharpDX application我的 SharpDX 应用程序中的内存泄漏
【发布时间】:2014-09-14 18:56:29
【问题描述】:

此代码每 100 毫秒运行一次。内存使用量不断增加,直到达到 1.5 GB,然后崩溃。

void takeScreenShot()
{
    Surface s;
    s = CaptureScreen(); 
    pictureBox1.Image = new Bitmap(Surface.ToStream(s, ImageFileFormat.Bmp));
    s.Dispose();
}

public Surface CaptureScreen()
{
    int width = Screen.PrimaryScreen.Bounds.Width;
    int height = Screen.PrimaryScreen.Bounds.Height;
    Device device = new Device(new Direct3D(), 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters(width, height));
    DisplayMode disp = device.GetDisplayMode(0);
    Surface s = Surface.CreateOffscreenPlain(device, disp.Width, disp.Height, Format.A8R8G8B8, Pool.Scratch);
    device.GetFrontBufferData(0, s);
    return s;
} 

【问题讨论】:

  • 不能重用CaptureScreen方法中的一些对象吗?喜欢DeviceSurface?当它崩溃时会发生什么?您是否收到异常或其他形式的反馈?
  • if (pictureBox1.Image != null) pictureBox1.Image.Dispose();
  • @HansPassant pictureBox1.Image.Dispose(),否则这也是我的猜测。

标签: c# memory directx sharpdx


【解决方案1】:

您每次都在创建一个新设备。

您应该只创建一次设备,在您的启动代码中创建一次,然后继续使用它。

此外,我怀疑Surface.ToStream() 中的内存泄漏,返回的流可能也需要处理。

       var stream = Surface.ToStream(s, ImageFileFormat.Bmp);
       pictureBox1.Image = new Bitmap(stream);
       stream.Dispose();

正如 Hans Passant 所说,Bitmap 也需要处理。

您可以通过帮助器非常轻松地调试 SharpDX 中的内存泄漏,以对未释放的 COM 资源进行诊断。在应用程序的开头设置此变量:

SharpDX.Configuration.EnableObjectTracking = true;

当您的应用程序退出时,它会打印一份关于未通过堆栈跟踪正确释放的 COM 对象的报告。这背后的类是ObjectTracker

ObjectTracker.ReportActiveObjects() 可以被调用以在运行时打印当前使用的资源(即使有堆栈跟踪)。

【讨论】:

  • 我可以确认 Surface.ToStream() 正在泄漏内存,但是如何处理返回的流?
  • 查看我的编辑,我认为您缺少一些基本概念
  • var 只是一个编译器关键字,没有“var stream”之类的东西。
  • @Shiro 我建议切换到积极维护的 SharpDx
  • @thumbmunkeys 我尝试使用这个和他们的"ScreenCapture" 示例,但由于我的显卡驱动程序(根据论坛),我遇到了一些运行时错误,我无法让它工作跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2013-03-26
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多