6.4. Regenerace s počítáním odkazů

Pro každý přidělený blok paměti můžeme udržovat informaci o počtu odkazů, které na tento blok ukazují. Při každém kopírování odkazu typu L := R se čítač odkazů bloku, na který ukazuje R, zvýší, zatímco čítač odkazů bloku, na který odkazoval původní ukazatel L, se sníží. Paměť pak může být uvolněna v případě, že se čítač odkazů sníží na nulu a na blok paměti tedy neukazuje žádný ukazatel.

Obrázek 6.1. Čítače odkazů

Je-li blok z paměti uvolněn, sníží se čítače odkazů i u všech objektů, na které z uvolněného bloku vede nějaký odkaz. To může způsobit kaskádu dalších uvolňování objektů - například pokud se uvolní objekt, odkazující se jako jediný na složitou datovou strukturu, mohou se všechny čítače odkazů na objekty v této struktuře dostat na nulu a tyto objekty se pak mohou uvolnit. Toto tranzitivní uvolňování objektů může být časově značně náročné a může vést ke zhoršení odezvy programu. Je však možné požadavky na uvolňování řadit do fronty a provádět je pak souběžně s činností aplikace. To činí metodu počítání odkazů zvlášť vhodnou pro aplikace pracující v reálném čase, kdy je třeba zajistit dostatečně rychlou odezvu systému.

Nevýhodou počítání odkazů je, že tuto metodu nelze použít v případě cyklických odkazů mezi objekty. Tehdy na sebe mohou bloky ukazovat navzájem a jejich čítač odkazů bude vždy nenulový, a to i v případě, že na tyto bloky již žádný další odkaz existovat nebude. Není tedy zaručena úplná regenerace nedostupné paměti. Problému cyklických odkazů je možné se vyhnout například tak, že tuto metodu omezíme pouze na struktury, u nichž k cyklickým odkazům dojít nemůže - např. na řetězce nebo jiná data neobsahující ukazatele. Pro zbývající struktury pak můžeme použít jinou metodu, případně lze použít čítače odkazů na všechny struktury a jinou metodu využít až při nahromadění většího počtu neodstranitelných objektů s cyklickými odkazy.

Metoda regenerace s počítáním odkazů má velmi malou paměťovou režii, která spočívá v připojení čítače ke každému přidělenému bloku paměti. Velikost čítače určuje nejvyšší počet odkazů, které mohou na blok ukazovat; je-li tento počet překročen, je možné například ponechat hodnotu čítače stále na maximální hodnotě, což v důsledku vede k tomu, že tento blok již nelze regenerovat.

Větší režii však tato metoda přináší v okamžiku, kdy dochází k častému vzniku a zániku objektů nebo při častých přesunech odkazů. Je-li například odkaz na objekt předán jako parametr funkce, zvýší se při volání funkce čítač odkazů a krátce na to se při návratu čítač opět vrací na původní hodnotu. Ke vzniku a okamžitému zániku dočasných objektů také dochází při vyhodnocování některých typů výrazů. Tato režie se může redukovat tzv. odloženým počítáním odkazů, kdy se při operacích nad lokálními proměnnými čítače neaktualizují okamžitě, ale pouze v jistých časových intervalech.