Nedílnou součástí návrhu distribuovaného objektového modelu je způsob adresování objektů. Cílem bylo navrhnout takové adresování, které by dobře skrývalo rozdíly mezi lokálními a vzdálenými objekty, umožňovalo objekty efektivně dohledávat a přitom bylo jednoduché na použití. Připomeňme, že základním požadavkem bylo umožnit migrace objektů, a to pokud možno s co nejmenší asistencí ze strany uživatele. Řada konkurenčních projektů (například CORBA) řeší tento problém tak, že migrace jednoduše neumožňuje a tím problém adresování a vyhledávání objektů výrazně zjednoduší (do identifikace objektu tak může uložit přímo síťovou adresu počítače, kde byl objekt vytvořen). Další, neméně důležitá vlastnost, je způsob, jakým je prováděno mapování z abstraktních identifikací do adresových prostorů počítačů, jak vypadá API pro používání takových identifikací (k čemu vůbec lze identifikace využít, jak lze pracovat se vzdálenými objekty), a zda je mapování obousměrné. Některé middlewary sice umožňují komunikovat se vzdáleným serverem, ale už neumožňují získat tuto referenci v "přenositelné" formě a předat ji nějakému dalšímu serveru. Dále jsme předpokládali, že v systému bude mnoho dynamických short-lived objektů, což kromě otázky, jak generovat identifikace pro nově vytvářené objekty, přináší nutnost rozhodnutí, jakým způsobem bude řízena doba života objektů (explicitně nebo nějaká forma Garbage Collectoru?). Původně jsme předpokládali, že objekty budou mazány explicitně programátorem distribuované aplikace.
V Massivu jsme zavedli abstraktní způsob identifikace objektů, kdy každý nově vytvořený objekt obdrží 64-bitové číslo, které jej identifikuje (zde si dovolím malou odbočku: Massiv podporuje i instanciaci dočasných objektů na programovém zásobníku nebo vkládání objektů do kontejnerů; tyto objekty nejsou přímo adresovatelné a tudíž nemají žádný identifikátor). Toto číslo nazýváme ObjectId a z implementačních důvodů je interpretováno jako n-tice, kde základní složky jsou identifikace tzv. object providera (který identifikátor vygeneroval), pořadové číslo objektu vzhledem k danému object providerovi a volitelně typová informace o objektu. Toto umožňuje, aby object id mohla být generována nezávisle na sobě. Objekty jsou pak dohledávány na základě prohledávání vyrovnávacích pamětí object providerů, globálním vyhledáváním, přímým dotazem na object provider, který daný identifikátor vygeneroval, nebo kombinací těchto metod. jednou vygenerované ObjectId je neměnné a v žádném případě nesouvisí s identifikací serveru. ObjectId nejsou recyklovány. Na aplikační úrovni se programátor aplikace v běžném případě s ObjectId vůbec nesetká.
Zatímco způsob adresace objektů byl zřejmý již během psaní specifikace, způsob mapování do aplikace a API pro práci bylo třeba dále dořešit. Původně se předpokládalo, že programátor aplikace bude muset ručně žádat systém o převody ObjectId na lokální reference a bude muset spolupracovat s jádrem při migracích objektů (uvolnění lokálních nativních referencí) - persistentní by byly pouze ObjectId, nikoliv reference. Neexistoval by koncept persistentní reference, která by skrývala rozdíl mezi lokální a vzdálenou referencí. Takové řešení by bylo přijatelné nejvýše pro programátory v C, nikoliv C++. Ukázalo se, že jediné rozumné řešení je naimplementovat vlastní reference jako C++ objekty (často označované jako tzv. smart pointers), které by obalovaly ObjectId a umožňovaly ObjectId "dereferencovat" (provádět převod na lokální reference podle potřeby). Po řadě vylepšeních technického rázu byl naimplementován ObjectPointer, který se dereferencuje na tzv. proxy objekty, které jsou napojeny buď přímo na lokální instance objektů (a umožňují přistupovat ke všem atributům a metodám objektu tak, jako kdyby se pracovalo s nativní referencí) nebo provádějí RPC volání (umožňují volat jen metody popsané v IDL). Vznikly tak persistentní reference s lokální nebo vzdálenou sémantikou, přičemž z hlediska způsobu použití a syntaktické deklarace obě vypadají stejně.
Další zásadní věcí, kterou bylo třeba ujasnit, bylo jakým způsobem se budou určovat migrační a replikační skupiny objektů. Narozdíl od konkurenčních projektů se nepředpokládalo, že implementace serverů použije pár statických vzdáleně adresovatelných objektů, ale že takových objektů bude mnoho, budou vytvářeny dynamicky a budou moci libovolně migrovat. To vedlo k nutnosti umožnit definovat tzv. migrační skupiny, kdy požadavek na migraci libovolného objektu ze skupiny vynutí migraci celé skupiny. To by mělo ten důsledek, že programátor by se mohl spolehnout na fakt, že objekty v rámci migrační skupiny budou vždy na stejném serveru, což by automaticky pomohlo ke snížení datových toků mezi servery. Opět původní idea, kdy příslušnost do migračních skupin bude určována explicitně, například tak, že v rámci skupiny bude vybrán vždy jeden master objekt a ostatní objekty budou migrovat podle něj, vzala brzy za své, protože při změnách migračních skupin by bylo neúnosné ručně aktualizovat napojení objektů na master objekt. Místo toho anotujeme reference a migrační skupiny jsou pak určeny implicitně na základě propointerování objektů. Podobně se určují replikační skupiny. Díky tomu dostává programátor do rukou "rozumné migrace a replikace" úplně zadarmo. Toto je jedna ze zásadních vlastností Massivu, které jej činí výjimečným.
S ohledem na fakt, že jádro musí tak jako tak znát všechny reference, byl již jen krůček k naimplementování Garbage Collectoru. Původně se uvažovalo o distribuované verzi, ale následně, po zhodnocení situace, kdy žádné v praxi používané middlewary distribuovaný Garbage Collector neimplementují, vyžadují spolupráci programátora nebo neumožňují detekovat cykly v referencích vedoucích přes více serverů, omezili jsme se na lokální verzi, tj. Garbage Collector s lokální sémantikou.
Výsledný model: reference jsou opatřeny atributy, které popisují jejich vztah vzhledem k činnosti Garbage Collectoru a definici migračních a replikačních skupin. Základním typem jsou tzv. strong reference, které implicitně definují migrační skupiny a u kterých jádro zajišťuje, že referencovaný objekt je vždy na stejném serveru jako příslušná reference. Strong reference mají lokální sémantiku a umožňují přistupovat ke všem atributům a metodám objektů. Na druhé straně weak reference mohou ukazovat na vzdálené objekty a mohou mít volitelně buď vzdálenou sémantiku (dereference znamená RPC) nebo lokální (chyba při přístupu, pakliže objekt není lokální). Činnost GC znamená detekování objektů, které nejsou dostupné z programového zásobníku nebo tzv. speciálních GC root objektů přes strong reference, a jejich následné mazání. Pro účely implicitních definic skupin objektů jsou reference interpretovány jako kdyby byly obousměrné. To zajišťuje, že migrační skupina referencovaného objektu a referencujícího objektu jsou stejné, a že je jádro schopno zaručit požadavek, že strong reference vždy ukazují na lokální objekty. Toto má ten důsledek, že běh GC se může omezit jen na lokální objekty.
Jak je vidět, největšího odklonu od specifikace (směrem k lepšímu) došlo právě v této oblasti, kdy současný stav je nesrovnatelný s již dost megalomanskou specifikací. Výsledkem je systém, který dosahuje o hodně vyššího stupně transparence než konkurenční systémy nebo implementuje funkce, o kterých by v těchto systeméch nemohlo být vůbec řeči. Jmenujme například CORBU, kde ORB nemá kontrolu nad všemi referencemi, neumožňuje migrace ani replikace objektů a při práci s objekty je třeba rozlišovat mezi prací se servant objekty přes lokální reference a prací se vzdálenými objekty přes CORBA reference (v Massivu se pracuje jednotně jen s jedním typem referencí, který umožňuje přímý přístup k atributům objektů a obyčejným ne-RPC metodám). Díky implementaci jádra a aplikačního kódu ve stejném jazyku a využití jedinečných vlastností C++ (templates) dochází k většímu stupni integrace a transparence.
dalsi vyhody massiv: vysoce optimalni bitove serializace versus portable textove serializace