Autor Téma: Uklízení nepotřebných DLL  (Přečteno 7872 krát)

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1574
  • Karma: 37
    • Pepak.net
Uklízení nepotřebných DLL
« kdy: 12-10-2012, 16:43:39 »
Kód: Delphi [Vybrat]
  1. procedure FreeDummyLibraries;
  2. var
  3.   I: Integer;
  4. begin
  5.   I := GetModuleHandle('OleAut32'); if I <> 0 then FreeLibrary(I);
  6.   I := GetModuleHandle('Ole32'); if I <> 0 then FreeLibrary(I);
  7.   I := GetModuleHandle('RPCRT4'); if I <> 0 then FreeLibrary(I);
  8.   I := GetModuleHandle('AdvAPI32'); if I <> 0 then FreeLibrary(I);
  9.   I := GetModuleHandle('GDI32'); if I <> 0 then FreeLibrary(I);
  10.   I := GetModuleHandle('COMCTL32'); if I <> 0 then FreeLibrary(I);
  11.   I := GetModuleHandle('USER32'); if I <> 0 then FreeLibrary(I);
  12. end;
  13.  
tj. uvolní po inicializaci všechny DLL co vyloženě nepotřebuje. Nevím, zda to má v současnosti ještě nějaký význam, ale z principu se mi to líbí.
1) Z principu by se mi víc líbilo, kdyby ty knihovny ani neimportoval, než aby je naimportoval, realokoval, a pak zahodil.
2) Kód knihoven by v paměti systému měl být jen jednou, společně pro všechny aplikace, takže to, že to jedna aplikace uvolní, asi nic nepřinese. Já bych se na to díval spíš tak, že jsem si tímhle zbytečně prodloužil exáč o nějakých 256 bajtů...

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3541
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Uklízení nepotřebných DLL
« Odpověď #1 kdy: 12-10-2012, 18:25:39 »
2) Kód knihoven by v paměti systému měl být jen jednou, společně pro všechny aplikace, takže to, že to jedna aplikace uvolní, asi nic nepřinese. Já bych se na to díval spíš tak, že jsem si tímhle zbytečně prodloužil exáč o nějakých 256 bajtů...

Ne, ne, ne. Tohle platilo v době Windows 9x nebo možná ještě v dobách Windows 3.x.
Od Windows na NT jádře to určitě neplatí. V dnešní době běží každá aplikace se všemi knihovnami ve svém vlastním paměťovém prostoru a o ostatních vůbec neví. Každý process dostane svoji kopii DLL v paměti, za pomoci mapování souborů. Je to z důvodu stability - dříve se stávalo, že jeden process DLL nabořil a vše šlo do kytek. Navíc v dnešní době ještě např. ComCtrl nebo jak se to jmenuje se procesu dostane obraz DLL z WINSX cache z doby instalace (pokud o to instalátor požádal - to ale platí asi spíše pro MS VC)

http://social.msdn.microsoft.com/Forums/da/vcgeneral/thread/e7305aee-b4ef-459b-8296-800649005181
Embarcadero MVP - Czech republic

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1574
  • Karma: 37
    • Pepak.net
Re:Uklízení nepotřebných DLL
« Odpověď #2 kdy: 13-10-2012, 08:46:07 »
V dnešní době běží každá aplikace se všemi knihovnami ve svém vlastním paměťovém prostoru a o ostatních vůbec neví.
To se nijak nevylučuje s tím, co píšu - že ty DLL jsou v paměti jen jednou.

Citace
http://social.msdn.microsoft.com/Forums/da/vcgeneral/thread/e7305aee-b4ef-459b-8296-800649005181
Tohle se týká dat té knihovny, to má každý proces svoje. Ale netýká se to kódu knihovny.

Offline Vrtule

  • Mladík
  • **
  • Příspěvků: 54
  • Karma: 10
    • Verze Delphi: XE2
    • Jádro systému Windows
Re:Uklízení nepotřebných DLL
« Odpověď #3 kdy: 12-11-2012, 19:53:51 »
Citace
2) Kód knihoven by v paměti systému měl být jen jednou, společně pro všechny aplikace, takže to, že to jedna aplikace uvolní, asi nic nepřinese. Já bych se na to díval spíš tak, že jsem si tímhle zbytečně prodloužil exáč o nějakých 256 bajtů...
Pokud si dobře pamatuju, tak systém jednu knihovnu DLL může sdílet mezi více procesy, ale je to takové sdílení v uvozovkách, protože nezahrnuje propagaci změn. Funguje na bázi mechanismu copy on write – knihovna je sdílena mezi procesy tak dlouho, dokud ji některý z nich nezmění (nepřipřadí do její proměnné atd.). Jakmile se tak stane, daný proces obdrží privátní kopii stránky, na které změnu provedl.

Tím nedochází k propagaci změn v jednom procesu do procesů jiných. Pro fungování mechanismu copy on write je klíčový WP bit procesorového registru CR0 (bit Enable Write Protection). Pokud jej vypnete, což je z režimu jádra možné, a zapíšete do regionu paměti pod copy on write, začnou se dít zajímavé věci.

Copy on write má samozřejmě smysl hlavně v případě, že daná knihovna je namapována do všech procesů na stejnou virtuální adresu. Pokud tomu tak není, je nutné provést relokace, tudíž její obsah se liší a copy on write nelze příliš efektivně aplikovat.

Citace
1) Z principu by se mi víc líbilo, kdyby ty knihovny ani neimportoval, než aby je naimportoval, realokoval, a pak zahodil.
Také by se mi líbilo, kdyby byly importovány jen ty funkce, které jsou programem opravdu použity, ale Delphi má zřejmě příliš málo rozčleněné běhové knihovny, aby linker tuto optimalizaci mohl efektivně provést. Nebo taková optimalizace není dostatečně implementována, čemuž se mi nechce věřit.

Vzhledem k tomu, že většinu z těch DLL knihoven bude určitě používat nějaký jiný proces, tak si myslím, že tímhle uvolněním z adresového prostoru moc velké úspory nedosáhnete. Získáte více virtuálního adresového prostoru, což v některých případech může být u 32bitových aplikací výhodné, u 64bitových aplikací v tom nevidím žádný význam. Krom toho se může stát, že po úpravě programu začnete některou z těch knihoven nevědomky používat, což povede ke zlu.

A ten uvolňovací kód bude fungovat jen u 32bitových aplikací, protože Integer je 32bitový. Lepší by v tomto ohledu bylo užít NativeInt (NativeUInt) či Pointer.

Offline zdenek

  • Plnoletý
  • ***
  • Příspěvků: 142
  • Karma: 9
Re:Uklízení nepotřebných DLL
« Odpověď #4 kdy: 14-11-2012, 18:30:03 »
Vrtule to napsal přesně.

Valná většina dll je linkována na $4000... (počet nul si doplňte) a tak se většinou realokuje a tím se code nesdílí. Pokud je v projektu pár dopředu daných dll (nebo bpl), hodí se změnit bázovou adresu a urychlit načítání, případně umožnit sdílení mezi procesy. Třeba na terminálu to je velké plus.