我正在使用下面的代碼捕獲桌面快照。自動清理非託管內存
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()來刪除分配。內存消耗仍然很高。
如何改善上述代碼修復內存泄漏?有任何想法嗎?
我無法在Win 7桌面上重現此操作。如果我在一個小型測試應用程序中快速捕獲我的桌面(2560x1600),則報告的託管內存將在1.5 MB和5 MB之間反彈。如果我添加一個對'GC.Collect()的調用,它在1.7 MB左右保持穩定。任務管理器提交大小報告的總內存以及使用中的GDI對象數量也保持穩定。 – dbc
是否有機會通過中途拋出異常,從而跳過釋放內存? – dbc
忘記提及我調用CaptureDesktopAsImage()方法,如在此問題的服務器部分中所寫:http://stackoverflow.com/questions/27756389/c-sharp-stream-desktop-activity。就我測試而言,不會引發異常 – kunaguvarun