justinstenning / Direct3DHook

DirectX Capture and Overlays by using Direct3D API hooks
http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks
MIT License
580 stars 178 forks source link

Memory leak in ImageElement #45

Closed Guad closed 7 years ago

Guad commented 7 years ago

Upon further inspection using a bigger image, recreating a new ImageElement every frame does indeed create a memory leak.

Some code.

The bitmap created on start up: var bm = new Bitmap(/* path to big image*/);

The main loop:

using (Bitmap doubleBuffer = new Bitmap(ScreenSize.Width, ScreenSize.Height,
            PixelFormat.Format32bppArgb))
{
    using (var graphics = Graphics.FromImage(doubleBuffer))
    {
        graphics.DrawImage(bm, new Point(0, 0));
    }

    DirectXHook.SetBitmap(doubleBuffer);
}

Same results can be achieved by just calling SetBitmap without a doublebuffer.

DirectXHook.SetBitmap(bm);

SetBitmap method, where this.OverlayEngine.Overlays[0].Elements[1] is an ImageElement

((ImageElement)this.OverlayEngine.Overlays[0].Elements[1]).Dispose();
this.OverlayEngine.Overlays[0].Elements.RemoveAt(1);
this.OverlayEngine.Overlays[0].Elements.Add(new Common.ImageElement(bt, true)
{
    Location = new System.Drawing.Point(0, 0)
});

this.OverlayEngine.FlushCache();

Finally, FlushCache method

public void FlushCache()
{
    lock (_imageCache)
    {
        foreach (var dxImage in _imageCache)
        {
            dxImage.Value?.Dispose();
            ((ImageElement)dxImage.Key).Dispose();
        }

        foreach (var element in Overlays[0].Elements.OfType<ImageElement>())
        {
            DXImage result = ToDispose(new DXImage(_device, _deviceContext));
            result.Initialise(element.Bitmap);
            _imageCache[element] = result;
        }
    }
}

SharpDX.ObjectTracker output

Count per Type:
BlendState : 1
Buffer : 2
Device : 2
DeviceContext : 3
Effect : 1
InputLayout : 1
RenderTargetView : 1
ShaderResourceView : 2
SwapChain : 28
Texture2D : 50

Texture2D never goes above 50