我的应用程序使用一个TWebBrowser控件来加载网页。问题是,在关闭包含TWebBrowser的窗体后,所使用的内存并没有被释放。如果我打开和关闭窗体,内存使用量只会持续增加。
有一些帖子提到调用SetProcessWorkingSetSize()或CoFreeUnusedLibrariesEx()来解决这个问题,但我不确定这些是否是正确的解决方案。
有任何想法如何释放TWebBrowser使用的内存吗?
我的应用程序使用一个TWebBrowser控件来加载网页。问题是,在关闭包含TWebBrowser的窗体后,所使用的内存并没有被释放。如果我打开和关闭窗体,内存使用量只会持续增加。
有一些帖子提到调用SetProcessWorkingSetSize()或CoFreeUnusedLibrariesEx()来解决这个问题,但我不确定这些是否是正确的解决方案。
有任何想法如何释放TWebBrowser使用的内存吗?
browser.DefaultInterface.Document
替代 browser.Document
解决了我的内存泄漏问题。谢谢。 - Charles-HenriTOleControl
错误。 - Remy Lebeau使用TWebBrowser会在幕后执行许多工作,其中大部分与完整的Internet Explorer实例执行的工作相同。它对您隐藏,但仍然存在,很可能我们无法强制从内存中删除它。在页面加载之前和之间检查内存使用情况,并测试调用Navigate('about:blank');
时会发生什么。还要检查您的析构函数是否被正确调用,并考虑从OnClose或OnCloseQuery中调用Navigate('about:blank');
。我发现这确实有助于内存情况稍微好一点。
最好的解决方案是停止使用TWebbrowser。
CEF4Delphi是一个免费的库,它使用Chrome而不是Internet Explorer。始终保持最新和非常高效:
Uses Winapi.PsAPI;
...
{$IFDEF WIN32}
procedure TForm1.MemoryFree;
var
HandleCaptureProcessus: THandle;
UnProcessus: TProcessEntry32;
PIDProcessus: THandle;
HandleProcessus: THandle;
NameOfProcess: string;
begin
PIDProcessus := 4294967295;
NameOfProcess := ExtractFileName(Application.ExeName);
HandleCaptureProcessus := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
UnProcessus.dwSize := SizeOf(TProcessEntry32);
Process32First(HandleCaptureProcessus, UnProcessus);
repeat
if UnProcessus.szExeFile = NameOfProcess then
begin
PIDProcessus := UnProcessus.th32ProcessID;
Break;
end;
until not Process32Next(HandleCaptureProcessus, UnProcessus);
if PIDProcessus = 4294967295 then
begin
CloseHandle(HandleCaptureProcessus);
exit;
end;
HandleProcessus := OpenProcess(PROCESS_ALL_ACCESS, False, PIDProcessus);
EmptyWorkingSet(HandleProcessus);
CloseHandle(HandleProcessus);
end;
{$ELSE}
procedure TForm1.MemoryFree;
begin
//**
end;
{$ENDIF}
procedure TForm1.FreeMemory;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
end;
并且定时调用它
FreeMemory;
为释放内存,只需初始化新文档:
(WebBrowser.Document as IPersistStreamInit).InitNew;
这里
找到。即使使用TWebBrowser作为组件的表单被释放,线程仍然保持运行,并且每个新实例都会创建新的线程(因此内存消耗增加)。我没有找到解决方案,我尝试了许多方法,包括CoFreeUnusedLibrariesEx
,导航到about:blank
,但都没有帮助。这是一个严重的问题,因为创建几个表单实例会耗费许多系统资源。我的建议是隐藏表单,而不是释放它,因为似乎这里没有效果。 - TLama