Klasická správa paměti Mac OS - Classic Mac OS memory management

Okno „O tomto počítači“ Mac OS 9.1 zobrazující spotřebu paměti každé otevřené aplikace a samotného systémového softwaru.

Historicky klasický Mac OS používal formu správy paměti , která v moderních systémech upadla z laskavosti. Kritika tohoto přístupu byla jednou z klíčových oblastí, kterým se změna systému Mac OS X zabývala .

Původním problémem pro inženýry Macintosh bylo, jak optimálně využít 128 kB RAM, kterou byl stroj vybaven, na počítačovém hardwaru založeném na Motorola 68000 , který nepodporoval virtuální paměť . Vzhledem k tomu, že v té době mohl stroj spouštět pouze jeden aplikační program najednou a neexistovalo žádné pevné sekundární úložiště , inženýři implementovali jednoduché schéma, které dobře fungovalo s těmito konkrétními omezeními. Tato volba designu se neomezila dobře s vývojem stroje, což způsobilo různé potíže jak pro programátory, tak pro uživatele.

Fragmentace

Zdá se, že primárním zájmem původních inženýrů byla fragmentace - to znamená opakované přidělování a uvolňování paměti pomocí ukazatelů, které vedou k mnoha malým izolovaným oblastem paměti, které nelze použít, protože jsou příliš malé, i když celková volná paměť může být dostatečné k uspokojení konkrétního požadavku na paměť. K vyřešení tohoto problému použili inženýři společnosti Apple koncept přemístitelného popisovače , což je odkaz na paměť, který umožňoval přesunutí skutečných uvedených dat bez zneplatnění popisovače. Schéma společnosti Apple bylo jednoduché - popisovač byl jednoduše ukazatel na (nepřemístitelnou) tabulku dalších ukazatelů, což zase ukazovalo na data. Pokud požadavek na paměť vyžadoval zhutnění paměti, bylo to provedeno a tabulka s názvem blok hlavního ukazatele byla aktualizována. Samotný stroj implementoval dvě oblasti v paměti dostupné pro toto schéma - haldu systému (používanou pro OS) a haldu aplikace. Pokud byla spuštěna pouze jedna aplikace současně, systém fungoval dobře. Vzhledem k tomu, že při ukončení aplikace byla celá halda aplikace rozpuštěna, byla fragmentace minimalizována.

Systém správy paměti měl slabiny; halda systému nebyla chráněna před potulnými aplikacemi, jak by to bylo možné, kdyby architektura systému podporovala ochranu paměti , a to bylo často příčinou problémů a selhání systému. Kromě toho přístup založený na popisovači také otevřel zdroj programovacích chyb, kde nebylo možné zaručit, že ukazatele na data v takových přemístitelných blocích zůstanou platné napříč hovory, které by mohly způsobit pohyb paměti. To byl skutečný problém pro téměř každé systémové API, které existovalo. Z důvodu transparentnosti datových struktur vlastněných systémem v té době mohla rozhraní API udělat jen málo pro to, aby to vyřešila. Tudíž bylo na programátorovi, aby takové ukazatele nevytvářel, nebo je alespoň velmi pečlivě spravoval dereferencí všech popisovačů po každém takovém volání API. Vzhledem k tomu, že mnoho programátorů tento přístup obecně neznalo, časné programy Mac často trpěly poruchami, které z toho vyplývaly.

Palm OS a 16bitové Windows používají podobné schéma pro správu paměti, ale verze Palm a Windows ztěžují chyby programátoru. Například v systému Mac OS program, který převede popisovač na ukazatel, pouze zruší odkaz na popisovač přímo, ale pokud popisovač není uzamčen, může se ukazatel rychle zneplatnit. Hovory k zamykání a odemykání rukojetí nejsou vyvážené; deset volání, která HLock jsou vrácena jedním hovorem na HUnlock . V systémech Palm OS a Windows jsou úchyty neprůhledným typem a musí se na ně odkazovat MemHandleLock v systému Palm OS nebo Global/LocalLock Windows. Když je aplikace Palm nebo Windows dokončena s popisovačem, zavolá MemHandleUnlock nebo Global/LocalUnlock . Palm OS a Windows udržují počet bloků blokování; po třech hovorech na MemHandleLock se blok odblokuje až po třech hovorech na MemHandleUnlock .

Řešení problému vnořených zámků a odemykání může být přímé (i když zdlouhavé) využitím různých metod, které však narušují čitelnost přidruženého bloku kódu a vyžadují povědomí a disciplínu ze strany programátora.

Úniky paměti a zastaralé odkazy

Povědomí a disciplína jsou rovněž nezbytné, aby se zabránilo „únikům paměti“ (selhání uvolnění v rámci alokace) a zamezení odkazům na zastaralé úchyty po vydání (což obvykle vedlo k těžkému selhání - otravování v systému s jedním úkolem, potenciálně katastrofické, pokud běží jiné programy).

Přepínač

Situace se zhoršila s příchodem Switcheru , což byl způsob, jak pro Mac s 512 kB nebo více paměti spustit více aplikací najednou. To byl nezbytný krok vpřed pro uživatele, kteří považovali přístup typu jedna aplikace za velmi omezující. Protože se Apple nyní zavázal ke svému modelu správy paměti a také ke kompatibilitě s existujícími aplikacemi, byl nucen přijmout schéma, kde byla každé aplikaci přidělena vlastní hromada z dostupné RAM. Množství skutečné paměti RAM přidělené každé haldě bylo nastaveno hodnotou kódovanou do metadat každé aplikace, nastavenou programátorem. Někdy tato hodnota nestačila pro konkrétní druhy práce, takže nastavení hodnoty muselo být vystaveno uživateli, aby mu umožnilo vyladit velikost haldy tak, aby vyhovovala jeho vlastním požadavkům. Přestože byla tato ukázka detailu technické implementace populární mezi „ pokročilými uživateli “, byla v rozporu s filozofií uživatelů Mac. Kromě vystavení uživatelů esoterickým technickým podmínkám to bylo neefektivní, protože by byla vytvořena aplikace, která by popadla veškerou přidělenou RAM, i když by většinu z nich následně nevyužila. Jinou aplikací může být nedostatek paměti, ale nebude moci využít volnou paměť „vlastněnou“ jinou aplikací.

I když aplikace nemohla výhodně využívat hromadu sesterské aplikace, mohla by ji určitě zničit, obvykle nechtěným zápisem na nesmyslnou adresu. Aplikace, která omylem zachází s fragmentem textu nebo obrázku nebo s nepřiřazeným umístěním jako ukazatel, může snadno přepsat kód nebo data jiných aplikací nebo dokonce operačního systému, takže „číhá“ i po ukončení programu. Takové problémy mohou být nesmírně obtížné analyzovat a napravit.

Switcher se vyvinul v MultiFinder v systému 4.2, který se stal Process Managerem v systému 7 , a do té doby bylo schéma dlouho zakořeněno. Apple se pokusil obejít zjevná omezení - dočasná paměť byla jednou, kdy si aplikace mohla na krátkou dobu „vypůjčit“ volnou RAM, která ležela mimo jeho hromadu, ale u programátorů to bylo nepopulární, takže se problémy do značné míry nepodařilo vyřešit. Doplněk Vylepšení systému Apple 7 přidal „minimální“ velikost paměti a „upřednostňovanou“ velikost - pokud nebylo k dispozici upřednostňované množství paměti, mohl by se program spustit na minimálním prostoru, případně se sníženou funkčností. To bylo začleněno do standardního OS počínaje systémem 7.1, ale stále to neřešilo problém root.

Schémata virtuální paměti , která zpřístupnila více paměti stránkováním nevyužitých částí paměti na disk, byla zpřístupněna nástroji třetích stran, jako je Connectix Virtual , a poté společností Apple v systému 7 . To zvýšilo kapacitu paměti Macintosh za cenu výkonu, ale nepřidalo chráněnou paměť nebo nezabránilo zhutnění haldy správce paměti, které by zneplatnilo některé ukazatele.

32bitové čisté

Původně měl Macintosh 128 kB RAM, s limitem 512 kB. To bylo zvýšeno na 4 MB po zavedení Macintosh Plus . Tyto počítače Macintosh používaly procesor 68000 , 32bitový procesor, ale měly pouze 24 fyzických adresních řádků. Těchto 24 řádků umožnilo procesoru adresovat až 16 MB paměti (2 24 bajtů), což bylo v té době považováno za dostatečné množství. Limit RAM v návrhu Macintosh byl 4 MB RAM a 4 MB ROM , kvůli struktuře mapy paměti. To bylo opraveno změnou mapy paměti u Macintosh II a Macintosh Portable , což umožnilo až 8 MB RAM.

Protože paměť byla vzácným zdrojem, rozhodli se autoři systému Mac OS využít nevyužitý bajt v každé adrese. Původní správce paměti (až do příchodu systému 7) umístil příznaky do vysokých 8 bitů každého 32bitového ukazatele a popisovače . Každá adresa obsahovala příznaky jako „zamčené“, „očistitelné“ nebo „prostředek“, které byly uloženy v tabulce hlavních ukazatelů. Když byly použity jako skutečná adresa, byly tyto příznaky maskovány a CPU je ignoroval.

I když dobré využití velmi omezeného prostoru RAM, tento design způsobil problémy, když Apple představil Macintosh II, který používal 32bitový procesor Motorola 68020 . 68020 měl 32 fyzických adresních řádků, které dokázaly adresovat až 4 GB (2 32 bajtů) paměti. Příznaky, které správce paměti uložil ve vysokém bajtu každého ukazatele a popisovače, byly nyní významné a mohly by vést k adresování chyb.

Teoreticky mohli architekti systémového softwaru Macintosh svobodně měnit schéma „příznaky ve vysokém bajtu“, aby se tomuto problému vyhnuli, a udělali to. Například na počítačích Macintosh IIci a novějších HLock() a dalších API byla přepsána tak, aby implementovala uzamčení úchytů jiným způsobem, než je označení vysokých bitů úchytů. Ale mnoho programátorů aplikací v systému Macintosh a velká část samotného softwarového kódu systému Macintosh přistupovali k příznakům spíše než pomocí rozhraní API HLock() , která byla poskytnuta k jejich manipulaci. Tímto způsobem vykreslili své aplikace nekompatibilní se skutečným 32bitovým adresováním, což se stalo známým jako ne 32bitové čisté.

Aby se zastavilo neustálé zhroucení systému způsobené tímto problémem, systém 6 a starší běžící na 68020 nebo 68030 by přinutil stroj do 24bitového režimu a rozpoznal by a adresoval pouze prvních 8 megabajtů RAM, což je zjevná chyba v stroje, jejichž hardware byl zapojen tak, aby přijímal až 128 MB RAM - a jejichž produktová literatura tuto schopnost propagovala. U systému 7 byl systémový software pro Mac konečně 32bitový, ale stále zde byl problém špinavých ROM. Problém spočíval v tom, že rozhodnutí použít 24bitové nebo 32bitové adresování musí být učiněno velmi brzy v procesu spouštění, kdy rutiny ROM inicializovaly Správce paměti pro nastavení základního prostředí Mac, kde jsou načteny ROM a ovladače disků NuBus a popraven. Starší ROM neměly žádnou podporu 32bitové paměti správce, a proto nebylo možné zavést do 32bitového režimu. Překvapivě první řešení této chyby zveřejnila softwarová společnost Connectix , jejíž produkt MODE32 z roku 1991 znovu inicializoval Správce paměti a opakoval časné části zaváděcího procesu Mac, což umožnilo systému spustit do 32bitového režimu a umožnit použití všech RAM ve stroji. Společnost Apple poskytla licenci na software od společnosti Connectix později v roce 1991 a distribuovala jej zdarma. Macintosh IIci a později Motorola počítače Macintosh založených měl 32bitové čisté ROM.

Trvalo nějakou dobu, než byly aplikace aktualizovány, aby odstranily všechny 24bitové závislosti, a systém 7 poskytl způsob, jak přepnout zpět do 24bitového režimu, pokud byly nalezeny nekompatibility aplikace. V době migrace na PowerPC a System 7.1.2 byla 32bitová čistota pro vytváření nativních aplikací povinná a dokonce ani později Macy založené na Motorola 68040 nemohly podporovat 24bitový režim.

Orientace objektu

Vzestup objektově orientovaných jazyků pro programování Mac - nejprve Object Pascal , později C ++ - také způsobil problémy použitému paměťovému modelu. Zpočátku se zdálo přirozené, že objekty budou implementovány pomocí úchytů, aby se získala výhoda přemístitelnosti. Tyto jazyky, jak byly původně navrženy, používaly ukazatele na objekty, což by vedlo k problémům s fragmentací. Řešením implementovaným kompilátory THINK (později Symantec ) bylo použití interně Handles pro objekty, ale k jejich přístupu použít syntaxi ukazatele. To se zpočátku zdálo jako dobrý nápad, ale brzy se objevily hluboké problémy, protože programátoři nemohli říci, zda mají co do činění s přemístitelným nebo pevným blokem, a tak neměli žádný způsob, jak vědět, zda se mají zabývat zamykáním objektů nebo ne. Není nutné říkat, že to vedlo k obrovskému počtu chyb a problémů s těmito časnými implementacemi objektů. Pozdější kompilátoři se o to nepokusili, ale použili skutečné ukazatele, často implementující svá vlastní schémata přidělení paměti pro práci s paměťovým modelem Mac OS.

Zatímco model paměti Mac OS, se všemi svými inherentními problémy, zůstal tímto způsobem až do Mac OS 9 , kvůli vážným omezením kompatibility aplikací, rostoucí dostupnost levné RAM znamenala, že by si většina uživatelů mohla upgradovat cestu ven z roh. Paměť nebyla využívána efektivně, ale byla natolik bohatá, že se problém nikdy nestal kritickým. To je ironické vzhledem k tomu, že účelem původního návrhu bylo maximalizovat využití velmi omezeného množství paměti. Mac OS X nakonec celé schéma odstranil a implementoval moderní řídké schéma virtuální paměti . Podmnožina API starších paměťových modelů stále existuje pro kompatibilitu jako součást Carbon , ale mapuje se na moderního správce paměti ( malloc implementace bezpečná pro vlákna ) pod ním. Apple doporučuje používat kód Mac OS X malloc a free „téměř výlučně“.

Reference

externí odkazy