Automatická správa paměti deterministicky

28. 9. 2011 11:23 (aktualizováno) zboj

V souvislosti s uvedením nového Windows Runtime (WinRT) a faktem, že nemá garbage collector (GC), se vyrojila spousta pseudonázorů od „expertů“ na programovací jazyky. Pro rádobyprogramátory rozmazlené správou paměti v Javě či C# existují jen dva extrémy – GC a malloc/free. Jaký je však nejnovější trend ve Windows a Mac OS X (resp. iOS)?

Nejnovější clang přišel s tzv. Automatic Reference Counting (ARC). To znamená,  že překladač kromě převodu kódu generuje direktivy pro správu paměti, jimiž kód prokládá. Před vygenerováním nativního kódu jsou při optimalizaci některé z nich zase odstraněny, ale sémantika výsledného kódu pochopitelně zůstává zachována.

Zjednodušeně řečeno čítač referencí pro objekt je inkrementován vždy při přiřazení do nové proměnné. Naopak původnímu objektu v proměnné je čítač snížen. Dosáhne-li čítač hodnoty nula, objekt je odstraněn z paměti, protože už není potřeba (neexistují na něj žádné další reference). GC dělá v podstatě to samé, ale nedeterministicky, tj. nikdo neví, kdy se GC rozhodne nepotřebné objekty odstranit. Proto mají jazyky s GC vyšší nároky na paměť – paměť je sice korektně uvolňována (téměř neexistují úniky paměti – memory leaks), ale chvíli trvá, než se tak stane. Při deterministické správě paměti je objekt uvolněn hned, jakmile není potřeba – spotřeba paměti je tedy obecně značně nižší.

Kromě clangu používá stejnou techniku také WinRT. Na mobilních zařízeních to je ostatně rozumné, paměti není nazbyt a při multitaskingu se o ni aplikace často perou (a operační systém pak některé aplikace na pozadí násilně ukončí). Jediným problémem jsou při takovémto postupu cykly referencí. Dokumentace k WinRT se o nich zmiňuje jen letmo (zatím), u clangu naopak velmi podrobně. Takové cykly se řeší tzv. slabými referencemi, tj. odkazy na objekt, které neinkrementují čítač referencí. To se jeví jako dobrý nápad, ovšem po zániku objektu může taková reference odkazovat na již naplatný objekt. Clang takové reference automaticky nuluje, takže nikdy se nemůže stát, že by se vývojář snažil přistoupit k neplatnému objektu. Nanejvýš se mu odkaz změní „pod rukama“.

Doporučuji přečíst si podrobnou dokumentace k ARC na stránkách LLVM, většina čtenářů si tak značně rozšíří obzory. Doufám, že Microsoft brzy vylepší svou dokumentaci k WinRT – předpokládám, že použitá technologie je velmi podobná.

NB: Instanční proměnná třídy v ObjC s ARC se deklaruje @property (weak) MyClass* ivar, lokální proměnná pak __weak MyClass* ivar (to se hodí například v blocích, nechceme-li zvýšit čítač na self, lze použít __weak id me = self;).

Sdílet