Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自动清理非托管内存_C#_.net_Memory_Memory Management - Fatal编程技术网

C# 自动清理非托管内存

C# 自动清理非托管内存,c#,.net,memory,memory-management,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("gd

我正在使用下面的代码捕获桌面的快照

    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()以删除分配。内存消耗仍然很高


如何改进上述代码以修复内存泄漏?有什么想法吗?

试试下面的解决方案,可能会有帮助 为未管理的对象分配null,然后将其处置

使用下面的清理代码

GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(<your Unmanaged Object>);
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject();
如果任何对象都有close()和open()方法,那么在释放Com对象之前先提到close()


希望这能有所帮助。

我无法在Win 7桌面上复制此功能。如果我在一个小的测试应用程序中快速捕获我的桌面(2560x1600),报告的托管内存大约会反弹1.5到5 MB。如果我添加对
GC.Collect()
的调用,它将保持稳定在1.7MB左右。任务管理器提交大小报告的总内存以及使用中的GDI对象数也保持稳定。是否有可能中途引发异常,从而跳过释放内存?忘记提到我调用CaptureDesktopAsImage()方法,如此问题的服务器部分所述:。在我测试时没有引发异常。我应该在哪里调用GC.Collect()?在调用方法中还是在被调用方法中?感谢您概述这些步骤。如上面的评论所述,我应该在哪里调用GC.Collect()?完成互操作任务后,可能在bmp.Save(filePath)下面;bmp.Dispose();也谢谢你。GC.Collect()确实解决了这个问题