Bjorn Jacobs
Bjorn Jacobs

Reputation: 25

Memory leak in my SharpDX application

This code runs every 100 ms. The memory usage just keeps increasing until it hits 1.5 GB and then it crashes.

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;
} 

Upvotes: 2

Views: 2200

Answers (1)

thumbmunkeys
thumbmunkeys

Reputation: 20764

You are creating a new device every time.

You should create the device only once, create it in your startup code once and then keep using it.

Furthermore I suspect a memory leak in Surface.ToStream() the returned stream probably needs disposing too.

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

As Hans Passant mentioned, Bitmap needs disposing as well.

You can very easily debug memory leaks in SharpDX by a helper to make diagnostic about unreleased COM resources. Setup at the beginning of your application this variable:

SharpDX.Configuration.EnableObjectTracking = true;

When your application exit, It will a print a report of COM objects that were not properly released with the stacktrace. The class behind this is ObjectTracker.

ObjectTracker.ReportActiveObjects() can be called to print the currently used resources at runtime (even with stack trace).

Upvotes: 5

Related Questions