自动清理非托管内存
Cleanup unmanaged memory automatically
我正在使用以下代码捕获桌面快照。
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>);
如果任何对象有 close() 和 open() 方法,那么在释放 Com 对象之前提及 close() ..
希望对您有所帮助。
我正在使用以下代码捕获桌面快照。
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>);
如果任何对象有 close() 和 open() 方法,那么在释放 Com 对象之前提及 close() ..
希望对您有所帮助。