Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Pascal->TWebBrowser->Uvolňování RAM paměti

Dobrý den,
vytvářím webový prohlížeč v Turbo Delphi. Dynamicky vytvářím nové listy, na kterých se dynamicky vytvářejí komponenty TWebBrowser. Neuvolňuje se mi však po zavření listu RAM paměť.

Po vykonání TWebBrowser(FindComponent('WebBrowser'+inttostr(de letedpage))).Free; se neuvolní skoro žádná paměť.

Předpokládám tedy, že musím nejdříve smazat načtený obsah komponenty TWebBrowser a pak teprve uvolnit samotnou komponentu.

Nějaký nápad?

Děkuji

(Pro zajímavost: Po vytvoření sto dynamických listů (+WebBrowserů) s načtením stránky Google.cz program využívá okolo 500MB RAM paměti. Po provedení Free včech komponent TWebBrowser klesne využití RAM paměti asi o 5MB)

Předmět Autor Datum
Ono záleží aj ako vytváraš komponentu...Predpokladám dynamicky za behu programu? Nastavuješ komponen…
pme 09.02.2012 17:44
pme
Ano, stačilo by pravděpodobně Document:=Nil, je však Read-Only. TWebBrowser vytvářím až za běhu prog…
Telever 09.02.2012 18:26
Telever
Pokiaľ vytváraš komponenty dynamicky a neskôr ich chceš uvoľniť za behu programu, vždy použi nil ako…
pme 09.02.2012 18:44
pme
Při použití Nil však program spadne hned jak přistoupím na kteroukoliv vlastnost komponenty přes TWe…
Telever 09.02.2012 19:19
Telever
FreeAndNil(); Neuvolní paměť žádnou. Ještě se o 1MB zvýší využití RAM.
Telever 09.02.2012 19:36
Telever
Zkus pred odstranenim listu zavolat Navigate s adresou 'about:blank'
Jan Fiala 09.02.2012 20:42
Jan Fiala
Nepomáhá.
Telever 09.02.2012 21:52
Telever
No, celého si ma tak trošku "domotal". (Sám som sa domotal.. :-)) Z toho čo som pochopil tak máš hl…
pme 09.02.2012 21:05
pme
Chlape, s tím sis neměl dávat práci. To mám hotovo, potřebuji ale vyčistit ten TWebBrowser.Document…
Telever 09.02.2012 21:56
Telever
Ale jak by jsi při použití tvého kódu vytvářel další TTabSheety a jak přistupoval k přibívajícím TWe…
Telever 09.02.2012 21:58
Telever
Ako pristupovať k TWebBrowserom? Jednoduché napr: (píšem z hlavy, tak sú možno chyby):-) function m…
pme 10.02.2012 07:36
pme
Vyzkoušel jsem a nic. Pravděpodobně je to kvůli rozdílu Delphi 2010/Delphi 2006 Po spuštění: 992kB…
Telever 10.02.2012 16:14
Telever
Aha, ty uvolňuješ obě komponenty. Stačí přeci jenom TTabSheet ne? TWebBrowser se uvolní s ním.
Telever 09.02.2012 22:00
Telever
Skús môj uvedený kód vyššie s uvoľňovaním TTabSheet +TWebBrowser (ja som si ho samozrejme najprv vys…
pme 10.02.2012 07:38
pme
apsal jsem program v Delphi XE //Create procedure TForm1.Button3Click(Sender: TObject); var WB:TWeb… poslední
Telever 23.02.2012 18:44
Telever

Ono záleží aj ako vytváraš komponentu...Predpokladám dynamicky za behu programu? Nastavuješ komponente pri vytváraní vlastníka Create(AOwner)? Potom by si mal odstrániť komponentu: self.RemoveControl(WebBrowser) - ale naozaj bez celého kódu, je to špekulovanie...
Ešte môžeš experimentovať s TWebBrowser().Document :=nil, TWebBrowser().Free, TWebBrowser.nil, prípadne FreeAndNil(WebBrowser).

Ano, stačilo by pravděpodobně Document:=Nil, je však Read-Only. TWebBrowser vytvářím až za běhu programu. Za běhu je velmi často přejmenovávám.

Vytváření:

EmptyWebBrowser:=TWebBrowser.Create(MForm);
TWinControl(EmptyWebBrowser).Parent:=TTabSheet(FindComponent('WebTab'+IntToStr(TabNumber)));
TWinControl(EmptyWebBrowser).Name:='WebBrowser'+inttostr(TabNumber);
with TWebBrowser(FindComponent('WebBrowser'+IntToStr(TabNumber))) do
  begin    
    Tag:=TabNumber;
    .
    .
    .
  end;

Zničení:

1)

TWebBrowser(FindComponent('WebBrowser'+inttostr(deletedpage))).Free;

2)

self.RemoveControl(TWebBrowser(FindComponent('WebBrowser'+inttostr(deletedpage))));

V obou případech stejný dopad.

Pokiaľ vytváraš komponenty dynamicky a neskôr ich chceš uvoľniť za behu programu, vždy použi nil ako vlastníka pri vytváraní, skús takto:

EmptyWebBrowser:=TWebBrowser.Create(nil);
TControl(EmptyWebBrowser).Parent:=TTabSheet(FindComponent('WebTab'+IntToStr(TabNumber)));
TControl(EmptyWebBrowser).Name:='WebBrowser'+inttostr(TabNumber);
.
.
TWebBrowser(FindComponent('WebBrowser'+inttostr(deletedpage))).Free;

Při použití Nil však program spadne hned jak přistoupím na kteroukoliv vlastnost komponenty přes TWebBrowser(FindComponent('WebBrowser'+IntToStr(Ta bNumber)))
Došel jsme však k zajímavému objevu. Používám prohlížeč Opera. Vyzkoušel jsem, jak je to zde s uvolňováním RAM.

Využití RAM po zapnutí Opera
68 800
Využití RAM při 100listech Google.cz
654 000
Využití RAM po zavření všech listů
381 680

Z toho vyplývá, že se uvolnilo pouze 47% paměti RAM. Samozřejmě nevím, jestli je to tak normální. (Windows 7)

No, celého si ma tak trošku "domotal". (Sám som sa domotal.. :-))

Z toho čo som pochopil tak máš hlavný Formulár a na ňom PageControl, v ktorom potom dynamicky vytváraš listy (Tabsheet) a v nich následne TWebBrowser.
Čiže ja by som to riešil asi nasledovne:
1. Vytvoril by som proceduru, kde by sa dynamicky vytvárali TabSheet+WebBrowser:

procedure MainForm.CreateTabBrowser;
var
  ts: TTabSheet;
  WB: TWebbrowser;
begin
  // Vytvoriť nový TabSheet
  ts := TTabSheet.Create(PageControl);
  try
    // Priradiť vlastnosti TTabSheet 
    ts.PageControl := PageControl;
    ts.Parent := PageControl;
    if PageControl1.ActivePageIndex > 0 then ts.PageIndex := PageControl1.ActivePageIndex + 1
    else ts.PageIndex := 0;
  
    // Vytvoriť inštanciu TWebbrowser 
    WB := TWebbrowser.Create(ts);

    // vložiť TWebbrowser na TTabSheet
    TControl(WB).Parent := ts;
    // alebo:   Ts.InsertControl(WB);

    // Priradiť vlastnosti Webbrowser 
    WB.Align := alClient;
    WB.Silent := True;
    WB.Visible := True;

    PageControl.ActivePage := ts;
    WB.Navigate(sURL);
  except
    ts.Free;
  end;
end;

2. potom by som si vytvoril procedúru, kde by som zatváral napr. aktívny list aj s následným zrušením WebBrowsera:

procedure mainForm.CloseTab(Sender: TObject);
begin
  if PageControl.ActivePage.Controls[0] is TWebbrowser then
  begin
    (TWebbrowser(PageControl.ActivePage.Controls[0])).Free;
     PageControl.ActivePage.Free;
  end;
end;

Chlape, s tím sis neměl dávat práci. To mám hotovo, potřebuji ale vyčistit ten TWebBrowser.Document ;-) Vím, že nemusím ničit TWebBrowser, že můžu zničit rovnou TTabSheet. Nechtěl jsme do toho plést ještě TPageControl a proto jsem uvedl WebBrowser.Free. (Ve výsledku se při uvolnění TTabSheetu uvolní i TWebBroswser, ale to neřeší můj paměťový problém. Ovšem ta Opera mě překvapila.)

Ako pristupovať k TWebBrowserom?
Jednoduché napr: (píšem z hlavy, tak sú možno chyby):-)

function mainForm.GetWB: TWebBrowser;
begin
  result := TWebbrowser(PageControl.ActivePage.Controls[0]);
end;

procedure PristupkWB;
var
  WB: TWebBrowser;
begin
  WB:=GetWB;
  WB.NavigatePage... (alebo podobne...)
   .
   . ďalší kód atď.
end;

Vyzkoušel jsem a nic. Pravděpodobně je to kvůli rozdílu Delphi 2010/Delphi 2006

Po spuštění:
992kB
Po provedení 13x CreateTabBrowser
96 376kB
Po provedení 13x CloseTab
94 464kB

procedure TMainForm.Button1Click(Sender: TObject);
begin
  CreateTabBrowser;
end;
procedure TMainForm.CloseButtonClick(Sender: TObject);
begin
  CloseTab;
end;

procedure TMainForm.CreateTabBrowser;
var
  ts: TTabSheet;
  WB: TWebbrowser;
begin
  ts := TTabSheet.Create(PageControl);
  try
    ts.PageControl := PageControl;
    ts.Parent := PageControl;
    if PageControl.ActivePageIndex > 0 then ts.PageIndex := PageControl.ActivePageIndex + 1
    else ts.PageIndex := 0;
    WB := TWebbrowser.Create(ts);
    TControl(WB).Parent := ts;
    WB.Align := alClient;
    WB.Silent := True;
    WB.Visible := True;
    PageControl.ActivePage := ts;
    WB.Navigate('google.cz');
  except
    ts.Free;
  end;
end;
procedure TmainForm.CloseTab;
begin
  if PageControl.ActivePage.Controls[0] is TWebbrowser then
  begin
    (TWebbrowser(PageControl.ActivePage.Controls[0])).Free;
    PageControl.ActivePage.Free;
  end;
end;

apsal jsem program v Delphi XE

//Create
procedure TForm1.Button3Click(Sender: TObject);
var
  WB:TWebBrowser;
begin
   WB:=TWebbrowser.Create(Nil);
   TControl(WB).Parent:=form1;
   WB.Align:=alClient;
   WB.Silent:=True;
   WB.Visible:=True;
end;
//Navigate
procedure TForm1.Button1Click(Sender: TObject);
begin
  (Form1.Controls[form1.ControlCount-1] as TWebBrowser).navigate('google.com');
end;
//Free
procedure TForm1.Button2Click(Sender: TObject);
begin
  Form1.Controls[form1.ControlCount-1].Free;
end;

Po ukončení se však uvolní jen 2MB. Nemůže to být ještě něčím jiným ve Windows?

Zpět do poradny Odpovědět na původní otázku Nahoru