C# Using SharpDX DirectX9 Got Memory Leak Simply Create/Release Device.

shy akocat 21 Reputation points
2023-08-27T21:41:43.23+00:00

I'm encountering a memory leak when using SharpDX DirectX9.

I have done some simple memory profiler to find out the reason, but the problem is in unmanaged memory, that's hard for me to debug.

I pack a very simple demo to a zip file. https://1drv.ms/u/s!AtJdwfH_KBJjjV3kEpLpilZNME77?e=9l0myS

If the file cannot download, following codes also do.

  • (Optional) Create a WPF .net framework 4.8/4.8.1 project in Visual Studio.
  • Using Nuget to install SharpDX , SharpDX.Mathematics and SharpDX.Direct3D9.
  • Create and edit code in DX.cs
public class DX
{
    int width = 1200;
    int height = 1200;
    Direct3D d3d;
    Device device;

    public DX()
    {
        d3d = new Direct3D();
        device = new Device(
            d3d,
            0,
            DeviceType.Hardware,
            IntPtr.Zero,
            CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded,
            new PresentParameters(width, height, Format.A8R8G8B8, 2, MultisampleType.None, 0, SwapEffect.Discard, IntPtr.Zero, windowed: true, enableAutoDepthStencil: true, Format.D24X8, PresentFlags.None, 0, PresentInterval.Immediate));
    }

    ~DX()
    {
        device?.Dispose();
        d3d?.Dispose();
    }
}
  • Test memory leak of class DX.
  • (Optional) Add a Button and a TextBlock in MainWindow.xaml to observe. Add Click event to button. The TextBlock is not necessary, other way to inspect memory usage also do.
private void Button_Click(object sender, RoutedEventArgs e)
{
    long memBegin, memEnd;
    memBegin = Process.GetCurrentProcess().PrivateMemorySize64;
    DX9Test();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    memEnd = Process.GetCurrentProcess().PrivateMemorySize64;
    txt.Text += $"\nmemBegin = {memBegin:n0} B, memEnd = {memEnd:n0} B";
}

public void DX9Test()
{
    var dx9 = new DX();
}
  • The memory usage is increasing when it create and dispose dx9 device (not every time but overall). Why? It seems I have already dispose the device and d3d in order.
Developer technologies C#
{count} votes

1 answer

Sort by: Most helpful
  1. Viorel 122.6K Reputation points
    2023-08-28T08:30:35.36+00:00

    It is probably incorrect to call Dispose from ~DX( ). Maybe you should implement the IDisposable interface according to Visual Studio's suggestions:

    public class DX : IDisposable
    {
        . . .
    
        private bool disposedValue;
    
        protected virtual void Dispose( bool disposing )
        {
            if( !disposedValue )
            {
                if( disposing )
                {
                    // TODO: dispose managed state (managed objects)
    
                    device?.Dispose( );
                    d3d?.Dispose( );
                }
    
                // TODO: free unmanaged resources (unmanaged objects) and override finalizer
    
                // TODO: set large fields to null
    
                disposedValue = true;
            }
        }
    
        // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
        ~DX( )
        {
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
            Dispose( disposing: false );
        }
    
        public void Dispose( )
        {
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
            Dispose( disposing: true );
            GC.SuppressFinalize( this );
        }
    }
    

    Usage:

    public void DX9Test( )
    {
        using( var dx9 = new DX( ) )
        {
    
        }
    }
    

    The leaks seem to be much smaller. See a similar issue:

    Probably the real code will not create such multiple objects, or the internal memory will be released after normal usage of objects.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.