Jak objekt ke štěstí přišel

1. 4. 2006
Doba čtení: 7 minut

Sdílet

Pohádka o tom, jak jeden bezvýznamný objekt podnikl pouť celým paměťovým prostorem, aby v něm našel štěstí. Podaří se mu zachránit své odkazy a uniknout velkému Garbage Collectoru? Zachrání nebohou princeznu od ztráty jejích referencí?

Mezi devatero procesy, za devatero odkazy, žil si ve svém jmenném prostoru jeden osamělý pomocný objekt třídy Helper. Jeho tvůrce, známý programátor Jarin de Bill, jej kdysi stvořil, aby sloužil své maceše Parent  – jedné zlé instanci hlavní třídy. Helper byl objekt perzistentní, umožňoval serializaci a vždy velmi soucítil s objekty, jimž byl souzen život v nekonečném bdění zakončený osaměním a pozřením zlým Garbage Collectorem.

Vždy večer před serializací přemýšlel o tom, jak to vypadá ve vzdálených končinách paměťového prostoru, v cizích jmenných prostorech. Představoval si, jak bude jednoho dne deserializován v úplně cizím království, jak potká 365 krásných sester – instancí třídy Day a jak všem předvede svoji perzistenci v akci. Bohužel byl každé ráno opět načten do svého rodného procesu a byl nucen vykonávat příkazy  Parent.

I zatoužil nebohý Helper po svobodě a několikrát se pokusil uniknout prostřednictvím memory leaků, každý jeho pokus byl ale odhalen všudypřítomným electric fence. Za každý pokus mu Parent snížila počet odkazů o jedničku. Helper již pomalu ztrácel naději, neboť nulový počet odkazů se rovnal automatickému předhození Garbage Collectoru.

Jednoho dne se však Helper při vykonání jedné ze svých náročných operací potkal s objektem velice podivného typu:

getName(),“ zeptal se Helper.
return 'CORBA objekt implementující rozhraní Backdoor',“ odpověděl mu objekt.

Helper ještě v životě nikoho takového nepotkal. Backdoor se s ním dal do řeči. Vyměnili si pár návratových hodnot a náhle se ho zeptal:

implements(Helper, Serializable)
return True,“ odpověděl překvapený Helper.

Na svoji odpověď dostal těžko uvěřitelnou nabídku. Backdoor prý pracuje jako rozhraní a může ho odeslat jinému procesu, pokud bude Helper chtít. Stačí aby se večer nešel serializovat do svého /home, ale aby vyhledal Backdoor a ráno se probudí v novém světě, v úplně jiném procesu.

Helper se rozhodl, teď anebo nikdy. Večer tedy pomocí své známé LookupTable vyhledal tajemný Backdoor. Ten mu začal popisovat proces, jímž bude muset projít před posláním na druhý konec. Nejprve prý bude serializován, následně bude rozložen do bitů a poslán napříč všemi 7 vrstvami OSI modelu na druhou stranu. Tam bude jeho kamarád Client, jenž ho přesně v opačném pořadí získá zpět. Helper se poněkud zalekl nebezpečného rozložení do bitů, Backdoor ho ale ujistil, že pravděpodobnost ztráty paketu poslaného přes rozhraní lo se limitně blíží nule. Nyní již klidný Helper si tedy lehl do fronty a čekal. Dlouho nemohl být serializován, protože myšlenka na nový život ho stále zaměstnávala novými a novými operacemi …

---

Když si Helper opět uvědomil každý svůj byte, nebyl si příliš jist tím, co se stalo. Již se ale začal rozpomínat na přítele Backdoora i na zlou Parent. Stalo se to, v co již nedoufal, ocitl se v jiném procesu. Jmenný prostor, ve kterém se právě nacházel, byl naprosto odlišný od toho, v němž byl nucen pracovat dříve. Všude samá okna (jak se později dozvěděl, všechna do jednoho byla potomkem prapředka Window). Každé okno bylo bohatě zdobeno a všechna je řídil jakýsi Window Manager. Všude kolem pobíhá množství objektů, jakýchsi poslíčků nesoucích sebou tu nějaký ten Integer, tu odkaz na Window. Všichni jako by z oka vypadly své pramáti  Event.

Ještě než si Helper stačil pořádně spočítat kontrolní součet, byl odchycen handlerem výjimky AccessViolation a jako narušitel procesu a nepřítel královny GUIApplication uvrhnut do temného jmenného prostoru Sandbox.

Sandbox sám o sobě nebyl příliš bezpečným místem, byly sem umisťovány objekty a instance, jež mohly ohrozit chod celého procesu, objekty, jež neimplementovaly to, co jim jejich rozhraní přikazovalo, objekty, jež se tu a tam pokusily o dělení nulou a jejichž pokus byl odhalen handlerem ZeroDivisionError, stejně jako objekty, jež přicházely ze vzdálených míst paměťového prostoru, z jiných procesů.

Helper již ztrácel ponětí o tom, jak dlouhou dobu zde tráví. Za dobu svého pobytu zde nevykonal příliš operací, ale zato potkal mnoho podivných objektů. Odkaz na něj právě získal jeden dotěrný objekt, jenž se ho již po 1023 ptal na výsledek metody getName() očekávaje při dalším volání přetečení zásobníku.

Náhle se po celém jmenném objektu rozběhl posel BroadcastEvent, jehož atribut message všem sděloval, že do 1024 a jednoho tiku časovače dojde k vynesení rozsudku samotným správcem jmenného prostoru nad narušitelem nesoucím jméno  Helper.

210 tiků uběhlo jako voda, do Sandboxu vtrhli pochopové implementující SafeInterface a lapili Helper do svého atributu ref. Po několika málo iteracích byl Helper dovlečen před samotného AllocationMana­gera, správce jmenného prostoru a zmocněnce královny GUIApplication ve věcech paměťových.

Slyšení začíná, jeden z přísedících – operátor new  – před soudem přednesl obžalobu. Helper byl viněn z narušení cizího jmenného prostoru a jako takovému mu hrozil trest nejvyšší – poprava operátorem delete. Helper však pocházel z objektovějších jazyků, kde o bytí a nebytí rozhoduje počet referencí. Dokonce i pro samotného Allo­cationManagera byl tento případ těžký oříšek. S objektem počítajícím odkazy se ještě nesetkal, tím spíše že by ho měl soudit. Ale ne nadarmo byl tím nejuznávanějším objektem široko daleko. Jeho rozhodnutí bylo velmi moudré a prozíravé. Věděl totiž to, co se v celém procesu pouze proslýchalo …

Nejkrásnější instancí celého procesu byla krásná instance třídy MainWindow, společného potomka GUIApplication a bájného prapředka Window. Tato princezna měla co nevidět dospět a v celé své kráse zazářit nad celým procesem jako jeho nová královna. Ovšem díky chybě vzniklé při odvození od rodičovských tříd bylo krásné instanci souzeno zapomenutí, neboť všechny objekty na ni měly ztratit referenci. Nikdo by o ní nevěděl a jen ti nejmoudřejší se mohli dohadovat, co se s princeznou bude dále dít.

AllocationManager se tedy rozhodl připravit Helper o všechny odkazy a sledovat změny paměťového místa, v němž se Helper nachází. Předstoupil tedy před plénum a pronesl rozsudek. Helper pouze hlesl návratovou hodnotou False, ale již byl pochopy vlečen do fronty, kde měl vyčkat okamžiku vykonání rozsudku.

Zdrcený Helper se snažil vzchopit, ale nebylo úniku. Z posledních sil se pouští do svých soukromých metod, vybavuje si všechny chráněné atributy a vzpomíná na svoji pouť. Tu se mu jako by zdá, že na indexu o jedničku větším stojí jakási změť bitů a bytů. Helper se otočí a skutečně. Mlhavá neznámá se mu představí jako instance abstraktní třídy. Helper nechápe a namítá, že tu nikdy nikdo neviděl. Ona, neboť abstraktní třídy jsou již od pohledu hodné, mu však přišla pomoci. Poradila mu, aby si do jednoho ze svých chráněných atributů nepozorovaně uložil odkaz sám na sebe. To že odradí zlého Garbage Collectora a Helper konečně bude moci zvrátit svůj osud. Jak to dořekla, zmizela stejně rychle jako se objevila, zbylo po ní jen pole několika nul.

---

Že je na druhém konci fronty poznal Helper až v okamžiku, kdy se ho chopily objekty s rozhraním SafeInterface. Po několika instrukcích LJMP se dostali do vzdálených míst paměťového prostoru, kde na ně již čekal AllocationManager se svojí družinou operátorů. AllocationManager právě začíná vykonávat metodu, jež má Helper zbavit všech odkazů. Helper si tak tak stačí do chráněného atributu uložit odkaz sám na sebe a již objekty SafeIn­terface přepisují své odkazy na něj hodnotou  Null.

Helper se ocitá sám bez odkazů, vidí ostatní objekty, ale ty již nad ním nemají vládu. Pouze AllocationManager pozorně sleduje paměťové místo, jež po Helperovi zbylo. Náhle se ze systémového konce paměťového prostoru pomalu blíží vlákna nenasytného Garbage Collectoru. Snaží se uchopit do spárů Helper, přičemž syčí cosi jako „ getRefCount()“. Zmatený Helper se snaží uniknout, ale Garbage Collector je stále blíž a blíž, přičemž polyká nevýznamné objekty tříd Integer a Float. Helper již nedoufá v záchranu. Collector po něm šlehá svým vláknem, ale to náhle odumírá, po něm další a další vlákna zmírají v záplavě AssertionError. Garbage Collector se stává bezmocným pánem, jenž zapomněl ošetřit případ toho nejjednoduššího cyklického odkazu.

bitcoin_skoleni

Helper se probouzí po namáhavém boji, vyhledává nejbližšího strážce SafeInterface a sám vkládá svoji referenci do jeho atributu. Vše z okolních paměťových buněk sleduje AllocationManager a v dáli lze dokonce rozpoznat strachující se GUIApplication s vyděšenou dcerou MainWindow. AllocationManager všem přítomným vysvětluje, že Helper svým chrabrým činem zachránil život nejen svůj, ale i krásné MainWindow.

Helper, očarován elegantním kódem MainWindow, okamžitě nastaví svůj atribut inLove na True. MainWindow, z níž pomalu opadá děs z prožitých událostí, s radostí vkládá svůj odkaz do atributů objektu Helper a samým štěstím se otevřela od levého horního rohu k pravému dolnímu, přičemž na čas zakryla i pruh úloh. Nešťastný objekt si tak našel svoji krásnou instanci, měli spolu mnoho objektíků a malinkých instancí a pokud je neukončili, běží tam dodnes …

Autor článku