我有一个简单的程序,它每秒截取几次屏幕截图。我创建了一个简单的代码来执行此操作,我可以根据需要多次运行它并且它工作正常。但是当我将相同的代码放入一个线程并运行它时,内存使用量开始上升,直到应用程序耗尽资源(大约 10 秒),然后线程当然会卡住。
为了测试,我有一个带有两个按钮的表单。一个运行上述代码,第二个启动一个运行相同代码的线程。我什至可以在第一个按钮上按住 Enter 键并且没有内存泄漏,但是当我单击第二个按钮时,线程会立即不断增加内存使用量(我什至可以使用 stop_thread 变量停止它,但内存使用量仍然很高)。
...
type
TMyThread = class(TThread)
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
var
Form1: TForm1;
stop_thread: Boolean;
my_thread: TMyThread;
...
constructor TMyThread.Create();
begin
inherited Create(true);
FreeOnTerminate:=true;
Suspended:=true;
end;
destructor TMyThread.Destroy;
begin
inherited;
end;
procedure TMyThread.Execute;
var screen_bmp: TBitmap;
desktop_hdc: HDC;
begin
while(stop_thread=false)do
begin
screen_bmp:=TBitmap.Create;
screen_bmp.PixelFormat:=pf32bit;
screen_bmp.Height:=Screen.Height;
screen_bmp.Width:=Screen.Width;
desktop_hdc:=GetWindowDC(GetDesktopWindow);
BitBlt(screen_bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, desktop_hdc, 0, 0, SRCCOPY);
ReleaseDC(GetDesktopWindow, desktop_hdc);
screen_bmp.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var screen_bmp: TBitmap;
desktop_hdc: HDC;
begin
screen_bmp:=TBitmap.Create;
screen_bmp.PixelFormat:=pf32bit;
screen_bmp.Height:=Screen.Height;
screen_bmp.Width:=Screen.Width;
desktop_hdc:=GetWindowDC(GetDesktopWindow);
BitBlt(screen_bmp.Canvas.Handle, 0, 0, Screen.Width, Screen.Height, desktop_hdc, 0, 0, SRCCOPY);
ReleaseDC(GetDesktopWindow, desktop_hdc);
screen_bmp.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
stop_thread:=false;
Button2.Enabled:=false;
my_thread:=TMyThread.Create;
my_thread.Resume;
end;
我知道问题与 BitBlt 线有关,因为没有它就没有内存泄漏。但我不明白发生了什么以及为什么发生。以及为什么当代码从主线程运行时没有发生。即使我将 Button1 代码放入一个循环并从主线程无休止地运行它,内存使用率仍然很低。有什么不同?
感谢您的任何建议!