自动清理非托管内存

时间:2015-01-05 05:31:51

标签: c# .net memory memory-management

我使用以下代码捕获桌面快照。

    using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;

namespace SMSServer
{
    class CaptureDesktop
    {
        // P/Invoke declarations
        [DllImport("gdi32.dll")]
        static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
        wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
        [DllImport("user32.dll")]
        static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
        [DllImport("gdi32.dll")]
        static extern IntPtr DeleteDC(IntPtr hDc);
        [DllImport("gdi32.dll")]
        static extern IntPtr DeleteObject(IntPtr hDc);
        [DllImport("gdi32.dll")]
        static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
        [DllImport("gdi32.dll")]
        static extern IntPtr CreateCompatibleDC(IntPtr hdc);
        [DllImport("gdi32.dll")]
        static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr ptr);

        private static string filePath = Directory.GetCurrentDirectory() + @"\CurrentImage.png";
        public void CaptureDesktopAsImage()
        {
            Size sz = Screen.PrimaryScreen.Bounds.Size;
            IntPtr hDesk = GetDesktopWindow();
            IntPtr hSrce = GetWindowDC(hDesk);
            IntPtr hDest = CreateCompatibleDC(hSrce);
            IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height);
            IntPtr hOldBmp = SelectObject(hDest, hBmp);
            bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0,         CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
            Bitmap bmp = Bitmap.FromHbitmap(hBmp);
            SelectObject(hDest, hOldBmp);
            DeleteObject(hBmp);
            DeleteDC(hDest);
            ReleaseDC(hDesk, hSrce);
            bmp.Save(filePath);
            bmp.Dispose();            
        }
    }
}

一切正常,但内存消耗过高。快速增长。在使用JetBrains dotMemory分析应用程序时,我发现它是由于上面的代码。我还看到在方法结束之前,调用Dispose()来删除分配。内存消耗仍然很高。

如何改进上述代码以修复内存泄漏?任何想法?

1 个答案:

答案 0 :(得分:0)

尝试以下解决方案,可能会有所帮助 为你的无人对象分配null,然后处理它..

使用以下清理代码

GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(<your Unmanaged Object>);

如果任何对象有close()和open()方法,那么在释放Com对象之前提及close()..

希望这有帮助。