Delphi XE2 中的 DCEF 内存泄漏
DCEF memory leak in Delphi XE2
我安装了以下版本的DCEF3https://github.com/hgourvest/dcef3
我启动一个新的 VCL 应用程序并删除 Chromium 组件。如果我 运行 这个应用程序我没有错误,但是如果我添加以下行:
procedure TForm2.Button3Click(Sender: TObject);
begin
Chromium1.Load('http://www.google.com');
end;
关闭应用程序时出现两次内存泄漏。
我尝试将 Chromium1.Load 部分移动到应用程序的另一部分,但内存泄漏仍然存在
以下是 MadExcept 的内存转储
allocation number: 1990
program up time: 529 ms
type: GetMem
address: 5afb0
size: 80
access rights: read/write
main thread ($cb0):
671cd312 madExcept32.dll madExceptDbg 1603 GetMemCallback
00404538 MyBrowser.exe System 290 @GetMem
0059ad91 MyBrowser.exe ceflib 12986 TCefBaseOwn.CreateData
0059e880 MyBrowser.exe ceflib 15920 TCefClientOwn.Create
005ab4cc MyBrowser.exe cefgui 648 TCustomClientHandler.Create
005aff37 MyBrowser.exe cefvcl 798 TVCLClientHandler.Create
005b03b2 MyBrowser.exe cefvcl 891 TCustomChromium.GetClientHandler
005b009f MyBrowser.exe cefvcl 830 TCustomChromium.Create
00478fa5 MyBrowser.exe System.Classes CreateComponent
004791d0 MyBrowser.exe System.Classes TReader.ReadComponent
00479481 MyBrowser.exe System.Classes TReader.ReadDataInner
004793c0 MyBrowser.exe System.Classes TReader.ReadData
0047f91d MyBrowser.exe System.Classes TComponent.ReadState
004f7aa3 MyBrowser.exe Vcl.Controls TControl.ReadState
004fc0bd MyBrowser.exe Vcl.Controls TWinControl.ReadState
00573bb9 MyBrowser.exe Vcl.Forms TCustomForm.ReadState
0047a343 MyBrowser.exe System.Classes TReader.ReadRootComponent
00476cde MyBrowser.exe System.Classes TStream.ReadComponent
00471b7f MyBrowser.exe System.Classes InternalReadComponentRes
00471cef MyBrowser.exe System.Classes InitComponent
00471d7d MyBrowser.exe System.Classes InitInheritedComponent
0057341a MyBrowser.exe Vcl.Forms TCustomForm.Create
0057df22 MyBrowser.exe Vcl.Forms TApplication.CreateForm
005bc649 MyBrowser.exe MyBrowser 17 initialization
76b2ef8a kernel32.dll BaseThreadInitThunk
memory dump:
0845afb0 a4 cf 45 08 4c 00 00 00 - 38 75 59 00 60 75 59 00 ..E.L...8uY.`uY.
0845afc0 90 75 59 00 f4 75 59 00 - 74 76 59 00 f4 76 59 00 .uY..uY.tvY..vY.
0845afd0 74 77 59 00 f4 77 59 00 - 74 78 59 00 f4 78 59 00 twY..wY.txY..xY.
0845afe0 74 79 59 00 f4 79 59 00 - 74 7a 59 00 f4 7a 59 00 tyY..yY.tzY..zY.
0845aff0 74 7b 59 00 f4 7b 59 00 - 74 7c 59 00 f4 7c 59 00 t{Y..{Y.t|Y..|Y.
allocation number: 1989
program up time: 529 ms
type: TVCLClientHandler
address: 5cfa4
size: 92
access rights: read/write
reference counter: 1
main thread ($cb0):
671cd312 madExcept32.dll madExceptDbg 1603 GetMemCallback
00404538 MyBrowser.exe System 290 @GetMem
0040587a MyBrowser.exe System 290 TObject.NewInstance
0040af04 MyBrowser.exe System 290 TInterfacedObject.NewInstance
00405eeb MyBrowser.exe System 290 @ClassCreate
005aff1d MyBrowser.exe cefvcl 797 TVCLClientHandler.Create
005b03b2 MyBrowser.exe cefvcl 891 TCustomChromium.GetClientHandler
005b009f MyBrowser.exe cefvcl 830 TCustomChromium.Create
00478fa5 MyBrowser.exe System.Classes CreateComponent
004791d0 MyBrowser.exe System.Classes TReader.ReadComponent
00479481 MyBrowser.exe System.Classes TReader.ReadDataInner
004793c0 MyBrowser.exe System.Classes TReader.ReadData
0047f91d MyBrowser.exe System.Classes TComponent.ReadState
004f7aa3 MyBrowser.exe Vcl.Controls TControl.ReadState
004fc0bd MyBrowser.exe Vcl.Controls TWinControl.ReadState
00573bb9 MyBrowser.exe Vcl.Forms TCustomForm.ReadState
0047a343 MyBrowser.exe System.Classes TReader.ReadRootComponent
00476cde MyBrowser.exe System.Classes TStream.ReadComponent
00471b7f MyBrowser.exe System.Classes InternalReadComponentRes
00471cef MyBrowser.exe System.Classes InitComponent
00471d7d MyBrowser.exe System.Classes InitInheritedComponent
0057341a MyBrowser.exe Vcl.Forms TCustomForm.Create
0057df22 MyBrowser.exe Vcl.Forms TApplication.CreateForm
005bc649 MyBrowser.exe MyBrowser 17 initialization
76b2ef8a kernel32.dll BaseThreadInitThunk
memory dump:
0845cfa4 b4 fd 5a 00 01 00 00 00 - fc 1d 40 00 b4 af 45 08 ..Z.......@...E.
0845cfb4 7c aa 58 00 70 ca 58 00 - 00 00 00 00 00 00 00 00 |.X.p.X.........
0845cfc4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cfd4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cfe4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cff4 00 00 00 00 b4 9f 5a 00 - 00 00 00 00 ......Z.....
我做错了什么?
在您的应用中试试这个。
关于项目来源:
Application.Initialize;
try
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
finally
if Assigned(form1) then
freeandnil(form1);
end;
和这个
initialization
ReportMemoryLeaksOnShutdown := (debugHook <> 0);
finalization
CheckSynchronize();
结果一样吗?
根据 your G+ thread, it was commented that this is indeed a bug in DCEF3.
切换到 DCEF4 will be a lot easier than back-porting the fix, just look at just the immediate complexity around the handling of the created TVCLClientHandler
instance:
function TCustomChromium.GetClientHandler: ICefClient;
begin
Result := TVCLClientHandler.Create(Self, False);
end;
作为开始,DCEF4 does much more here:
function TChromium.CreateClientHandler(aIsOSR : boolean) : boolean;
begin
Result := False;
try
if (FHandler = nil) then
begin
FIsOSR := aIsOsr;
FHandler := TVCLClientHandler.Create(Self, FIsOSR);
Result := True;
end;
except
on e : exception do
if CustomExceptionHandler('TChromium.CreateClientHandler', e) then raise;
end;
end;
我安装了以下版本的DCEF3https://github.com/hgourvest/dcef3
我启动一个新的 VCL 应用程序并删除 Chromium 组件。如果我 运行 这个应用程序我没有错误,但是如果我添加以下行:
procedure TForm2.Button3Click(Sender: TObject);
begin
Chromium1.Load('http://www.google.com');
end;
关闭应用程序时出现两次内存泄漏。
我尝试将 Chromium1.Load 部分移动到应用程序的另一部分,但内存泄漏仍然存在
以下是 MadExcept 的内存转储
allocation number: 1990
program up time: 529 ms
type: GetMem
address: 5afb0
size: 80
access rights: read/write
main thread ($cb0):
671cd312 madExcept32.dll madExceptDbg 1603 GetMemCallback
00404538 MyBrowser.exe System 290 @GetMem
0059ad91 MyBrowser.exe ceflib 12986 TCefBaseOwn.CreateData
0059e880 MyBrowser.exe ceflib 15920 TCefClientOwn.Create
005ab4cc MyBrowser.exe cefgui 648 TCustomClientHandler.Create
005aff37 MyBrowser.exe cefvcl 798 TVCLClientHandler.Create
005b03b2 MyBrowser.exe cefvcl 891 TCustomChromium.GetClientHandler
005b009f MyBrowser.exe cefvcl 830 TCustomChromium.Create
00478fa5 MyBrowser.exe System.Classes CreateComponent
004791d0 MyBrowser.exe System.Classes TReader.ReadComponent
00479481 MyBrowser.exe System.Classes TReader.ReadDataInner
004793c0 MyBrowser.exe System.Classes TReader.ReadData
0047f91d MyBrowser.exe System.Classes TComponent.ReadState
004f7aa3 MyBrowser.exe Vcl.Controls TControl.ReadState
004fc0bd MyBrowser.exe Vcl.Controls TWinControl.ReadState
00573bb9 MyBrowser.exe Vcl.Forms TCustomForm.ReadState
0047a343 MyBrowser.exe System.Classes TReader.ReadRootComponent
00476cde MyBrowser.exe System.Classes TStream.ReadComponent
00471b7f MyBrowser.exe System.Classes InternalReadComponentRes
00471cef MyBrowser.exe System.Classes InitComponent
00471d7d MyBrowser.exe System.Classes InitInheritedComponent
0057341a MyBrowser.exe Vcl.Forms TCustomForm.Create
0057df22 MyBrowser.exe Vcl.Forms TApplication.CreateForm
005bc649 MyBrowser.exe MyBrowser 17 initialization
76b2ef8a kernel32.dll BaseThreadInitThunk
memory dump:
0845afb0 a4 cf 45 08 4c 00 00 00 - 38 75 59 00 60 75 59 00 ..E.L...8uY.`uY.
0845afc0 90 75 59 00 f4 75 59 00 - 74 76 59 00 f4 76 59 00 .uY..uY.tvY..vY.
0845afd0 74 77 59 00 f4 77 59 00 - 74 78 59 00 f4 78 59 00 twY..wY.txY..xY.
0845afe0 74 79 59 00 f4 79 59 00 - 74 7a 59 00 f4 7a 59 00 tyY..yY.tzY..zY.
0845aff0 74 7b 59 00 f4 7b 59 00 - 74 7c 59 00 f4 7c 59 00 t{Y..{Y.t|Y..|Y.
allocation number: 1989
program up time: 529 ms
type: TVCLClientHandler
address: 5cfa4
size: 92
access rights: read/write
reference counter: 1
main thread ($cb0):
671cd312 madExcept32.dll madExceptDbg 1603 GetMemCallback
00404538 MyBrowser.exe System 290 @GetMem
0040587a MyBrowser.exe System 290 TObject.NewInstance
0040af04 MyBrowser.exe System 290 TInterfacedObject.NewInstance
00405eeb MyBrowser.exe System 290 @ClassCreate
005aff1d MyBrowser.exe cefvcl 797 TVCLClientHandler.Create
005b03b2 MyBrowser.exe cefvcl 891 TCustomChromium.GetClientHandler
005b009f MyBrowser.exe cefvcl 830 TCustomChromium.Create
00478fa5 MyBrowser.exe System.Classes CreateComponent
004791d0 MyBrowser.exe System.Classes TReader.ReadComponent
00479481 MyBrowser.exe System.Classes TReader.ReadDataInner
004793c0 MyBrowser.exe System.Classes TReader.ReadData
0047f91d MyBrowser.exe System.Classes TComponent.ReadState
004f7aa3 MyBrowser.exe Vcl.Controls TControl.ReadState
004fc0bd MyBrowser.exe Vcl.Controls TWinControl.ReadState
00573bb9 MyBrowser.exe Vcl.Forms TCustomForm.ReadState
0047a343 MyBrowser.exe System.Classes TReader.ReadRootComponent
00476cde MyBrowser.exe System.Classes TStream.ReadComponent
00471b7f MyBrowser.exe System.Classes InternalReadComponentRes
00471cef MyBrowser.exe System.Classes InitComponent
00471d7d MyBrowser.exe System.Classes InitInheritedComponent
0057341a MyBrowser.exe Vcl.Forms TCustomForm.Create
0057df22 MyBrowser.exe Vcl.Forms TApplication.CreateForm
005bc649 MyBrowser.exe MyBrowser 17 initialization
76b2ef8a kernel32.dll BaseThreadInitThunk
memory dump:
0845cfa4 b4 fd 5a 00 01 00 00 00 - fc 1d 40 00 b4 af 45 08 ..Z.......@...E.
0845cfb4 7c aa 58 00 70 ca 58 00 - 00 00 00 00 00 00 00 00 |.X.p.X.........
0845cfc4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cfd4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cfe4 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
0845cff4 00 00 00 00 b4 9f 5a 00 - 00 00 00 00 ......Z.....
我做错了什么?
在您的应用中试试这个。
关于项目来源:
Application.Initialize;
try
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
finally
if Assigned(form1) then
freeandnil(form1);
end;
和这个
initialization
ReportMemoryLeaksOnShutdown := (debugHook <> 0);
finalization
CheckSynchronize();
结果一样吗?
根据 your G+ thread, it was commented that this is indeed a bug in DCEF3.
切换到 DCEF4 will be a lot easier than back-porting the fix, just look at just the immediate complexity around the handling of the created TVCLClientHandler
instance:
function TCustomChromium.GetClientHandler: ICefClient;
begin
Result := TVCLClientHandler.Create(Self, False);
end;
作为开始,DCEF4 does much more here:
function TChromium.CreateClientHandler(aIsOSR : boolean) : boolean;
begin
Result := False;
try
if (FHandler = nil) then
begin
FIsOSR := aIsOsr;
FHandler := TVCLClientHandler.Create(Self, FIsOSR);
Result := True;
end;
except
on e : exception do
if CustomExceptionHandler('TChromium.CreateClientHandler', e) then raise;
end;
end;