Útržky - Trasování alokace a dealokace paměti

vložil Radek Červinka 6. října 2014 00:18

Znáte ten pocit, kdy Vás napadne podle Vás skvělá myšlenka, tu začnete implementovat a přijdete na to, že to v praxi nebude úplně přesně fungovat jak si člověk vymyslel, ale je Vám líto to vyhodit, protože jsou v tom určité myšlenky, které se někomu mohou hodit? Tak to je případ dnešního kódu.

Onehdy mne napadlo, že by bylo zajímavé se napíchnout na memory manager a zkusit nějak vyhodnocovat jeho volání a tento obsah pak použít jako podklad pro různé optimalizace, resp. hledání neefektivních částí programu.

Malá vsuvka pro neznalé: veškeré alokace a uvolňování včetně řetězců jdou přes 3 (5) funkcí. Na tyto funkce je navěšen správce paměti (většinou FastMM), který optimalizuje alokace dle potřeb Delphi programů. Je možné napsat (např. správce paměti bez optimalizace) - tj. přímo volání OS, ale je to pomalé řešení.

Takže jsem napsal malý unit, který se napíchne na tato volání a vypisuje velikosti alokací a uvolňování a adresu. Navíc při uvolňování špinavým trikem zjistí v případě, že se jedná o následníka TObject název třídy a pokud to není objekt, tak zkusí vypsat pár znaků jako kdyby to byl řetězec. Je to zkopírované z informací FastMM, ale je to přinejmenším zajímavé. Původně jsem myslel, že budu schopen i zobrazit jméno objektu v případě že se jedná o komponentu, ale v okamžiku uvolňování objektu je již řetězec s názvem komponenty uvolněn.

No jako cvičení to bylo zajímavé a třeba to někomu pomůže.

Jen poznámka: veškeré operace během alokace a uvolňování musí být psány s ohledem na to, že nesmí dojít k další alokaci, tj. pozor na řetezce atd.

Download: Memtrace (1K). Stačí přidat do uses, hned za FastMM (resp. co nejdříve v projektu).

Tagy: ,

Praxe

Komentáře

6.10.2014 3:27:11 #

Martin Dráb

Na alokační a dealokační rutiny se "napichuju" poměřně často, ač převážně v projektech, které jsou psané v C a běží blíže k OS (nízkoúrovňovější knihovny, ovladače). Vlastní alokační a dealokační rutiny (jedná se tedy spíše o obaly standardních rutin) dovolují zjišťovat memory leaky a částečně i zápis mimo alokovanou paměť (dojde-li k němu dostatečně blízko alokovaného bloku).

Zajímalo by mě, o kolik je "pomalé řešení" alokace zajišťované prostředky OS pomalejší, než řešení poskytované alokátorem v Delphi. Před pár lety jsem studoval, jak funguje heap manager ve Windows (alokační funkce HeapAlloc, HeapFree například) a myslím, že se v Microsoftu dost snažili, aby alokace i dealokace probíhaly hodně rychle (implementovali v podstatě exact-fit s pomocnou cache). Tím nechci tvrdit, že by v tomto Delphi nebylo lepší, ale zajímalo by mě to blíže.

Martin Dráb

6.10.2014 10:01:47 #

pf1957

Na zaklade toho mala, co vim o FastMM, kterym byl puvodni mizerny MM v Delphi nahrazen, bych rekl, ze jeho hlavni prinos je v alokaci kratkych bloku pameti, kdy se *hlavne* snazi celit defragmentaci pameti. Dela to tak, ze si alokuje pooly pro kusy pameti do velikosti cca 2,6 kB po 8 resp. 16 bytech. Chain poolu dane velikosti pri alokaci ziska pres tabulku, na pool s volnou polozkou pozadovane delky si udrzuje pointer, stejne jako na 1. volnou polozku. Pri zaplneni poolu ho vyjme ze seznamu pouzitelnych, pri uvolnovani polozek z plneho poolu ho vrati do seznamu pouzitelnych poolu a aktualizuje pointery, pokud je zcela prazdny, tak ho vrati systemu. Trochu v tom dela bordel multihreading, kdy zamyka, dela retry a v pripade busy dela zrejme (?) nahradni alokace o max. velikosti, aby nemusel kontrolovat overflow. Ma to asm verzi, ktera vypada, ze je docela usporne napsana, ale nikdy jsem se nedostal k tomu, abych to na necem realnem zmeril, o kolik by se to lisilo v pripade prime alokace pameti pres OS. Dnes uz v Delphi skoro nedelam, takze motivace se tim zabyvat je blizka nule. Pokud mas cas a chut, tak je to OSS: http://sourceforge.net/projects/fastmm/

pf1957

6.10.2014 10:02:56 #

radekc

Martina, záleží na co. http://scalemm.googlecode.com/svn/trunk/Challenge/Results/MMBench_all.htm

Obecně ještě FastMM není nejrychlejší v vícevláknech, tam je lepší třeba právě odkazovaný ScaleMM, ale z hlediska alokace malých bloků je to podle mne velmi významné. Zkus se podívat na ten odkaz.

radekc

6.10.2014 10:36:10 #

radekc

Pf, částečně máš pravdu, až na to že rozlišuje velikosti požadovaného bloku (>260K, >2.5K a malé <2.5K). Velké jsou alokovány přímo OS, u středních se alokuje po 1.25M a funguje jako pool, malé asi fungují jak popisuješ.

Je nutno řict, ze puvodni manager byl z doby Win95 a tehdy byl radove lepsi nez to co nabizelo Windows, takze tvoje soudy jsou celkem nespravedlivé.

radekc

6.10.2014 11:10:30 #

pf1957

Zamerne jsem popisoval jen male bloky, kde muze neco setrit, protoze na tech ostatnich v podstate jen pridava overhead, jak je koneckoncu videt i na tom benchmarku, cos sem daval. Jinak si myslim, ze puvodni manager byl z dob D1 (16 bit) nebo spis jeste z dob Turbo Pascalu, kdy stringove operace pouzivaly jako jeden operand "stringovy registr" na stacku a promenne byly implicitne  staticke nebo automaticke a ostatni alokace mel clovek do urcite miry pod kontrolou, takze zalezelo na nem, co s heapem udela. Ovsem pri prechodu na D2 (32bit) a zavedenim huge stringu a jejich presunutim na heap se vliv  droleni pameti zesilil za mez unosnosti.

pf1957

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců