Klasik Mac OS bellek yönetimi - Classic Mac OS memory management

Açık olan her uygulamanın bellek tüketimini ve sistem yazılımının kendisini gösteren "Bu Bilgisayar Hakkında" Mac OS 9.1 penceresi.

Tarihsel olarak, klasik Mac OS , modern sistemlerde gözden düşmüş bir bellek yönetimi biçimi kullanıyordu . Bu yaklaşımın eleştirisi, Mac OS X'teki değişikliğin ele aldığı temel alanlardan biriydi .

Macintosh mühendisleri için asıl sorun , makinenin donatıldığı 128 KB RAM'in sanal belleği desteklemeyen Motorola 68000 tabanlı bilgisayar donanımında en iyi şekilde nasıl kullanılacağıydı . O sırada makine bir seferde yalnızca bir uygulama programını çalıştırabildiğinden ve sabit ikincil depolama olmadığından , mühendisler bu belirli kısıtlamalarla iyi çalışan basit bir şema uyguladılar. Bu tasarım seçimi, makinenin geliştirilmesiyle iyi ölçeklenmedi ve hem programcılar hem de kullanıcılar için çeşitli zorluklar yarattı.

Parçalanma

Orijinal mühendislerin birincil endişesi parçalanma gibi görünmektedir - yani, hafızanın işaretçiler aracılığıyla tekrar tekrar tahsis edilmesi ve serbest bırakılması, çok küçük oldukları için kullanılamayan birçok küçük izole bellek alanına yol açmaktadır, ancak toplam boş bellek olabilir. belirli bir bellek talebini karşılamak için yeterli olacaktır. Bunu çözmek için, Apple mühendisleri yeniden konumlandırılabilir bir tutamaç kavramını kullandılar; belleğe referans olan bir referans, tutamacı geçersiz kılmaksızın referans verilen gerçek verilerin taşınmasına izin verdi. Apple'ın şeması basitti - bir tutamaç, daha sonra verilere işaret eden başka işaretçilerin (yeniden konumlandırılamayan) bir tablosuna bir işaretçiydi. Bir bellek talebi belleğin sıkıştırılmasını gerektiriyorsa, bu yapıldı ve ana işaretçi bloğu olarak adlandırılan tablo güncellendi. Makinenin kendisi, bu şema için kullanılabilen bellekte iki alan uyguladı - sistem yığını (işletim sistemi için kullanılır) ve uygulama yığını. Bir seferde yalnızca bir uygulama çalıştırıldığı sürece, sistem iyi çalıştı. Uygulama sona erdiğinde tüm uygulama yığını çözüldüğünden, parçalanma en aza indirildi.

Bellek yönetim sisteminin zayıf yönleri vardı; Sistem mimarisi bellek korumasını destekleseydi mümkün olacağı gibi sistem yığını hatalı uygulamalardan korunmuyordu ve bu genellikle sistem sorunlarının ve çökmelerinin nedeniydi. Buna ek olarak, tutamaç tabanlı yaklaşım aynı zamanda, bu tür yeniden konumlandırılabilir bloklar içindeki verilere yönelik işaretçilerin belleğin hareket etmesine neden olabilecek çağrılar arasında geçerli kalmasının garanti edilemediği bir programlama hatası kaynağı da açtı. Bu, var olan hemen hemen her sistem API'si için gerçek bir sorundu . O sırada sisteme ait veri yapılarının şeffaflığı nedeniyle, API'ler bunu çözmek için çok az şey yapabilirlerdi. Böylelikle programcı, bu tür işaretçileri yaratmama ya da en azından bu tür her API çağrısından sonra tüm tutamaçları referans alarak bunları çok dikkatli bir şekilde yönetme yükümlülüğüydü. Birçok programcı bu yaklaşıma genel olarak aşina olmadığından, ilk Mac programları bundan kaynaklanan hatalardan sık sık muzdaripti.

Palm OS ve 16-bit Windows, bellek yönetimi için benzer bir şema kullanır, ancak Palm ve Windows sürümleri, programcı hatasını daha zor hale getirir. Örneğin, Mac OS'de, bir tutamacı bir işaretçiye dönüştürmek için, bir program tutamaca doğrudan referansı kaldırır, ancak tutamaç kilitli değilse, işaretçi hızla geçersiz hale gelebilir. Tutamaçları kilitlemek ve kilidini açmak için yapılan aramalar dengeli değildir; yapılacak on çağrı, HLock tek bir çağrı ile geri alınır HUnlock . Palm OS ve Windows'ta, tutamaçlar opak bir tiptir ve MemHandleLock Palm OS veya Global/LocalLock Windows'ta ile referansları kaldırılmalıdır . Bir Palm veya Windows uygulaması bir tutamaçla bittiğinde, MemHandleUnlock veya Global/LocalUnlock . Palm OS ve Windows, bloklar için bir kilit sayımı tutar; Üç çağrı yapıldıktan sonra MemHandleLock , bir blok ancak üç çağrı yapıldıktan sonra açılır MemHandleUnlock .

İç içe geçmiş kilitler ve kilit açma sorununu ele almak, çeşitli yöntemler kullanarak basit (sıkıcı olsa da) olabilir, ancak bunlar ilgili kod bloğunun okunabilirliğine müdahale eder ve kodlayıcı tarafında farkındalık ve disiplin gerektirir.

Bellek sızıntıları ve eski referanslar

Bellek "sızıntılarını" (ayırma kapsamında ayrılamama ) ve serbest bırakıldıktan sonra eski tutamaçlara referanslardan kaçınmak için de farkındalık ve disiplin gereklidir (bu genellikle büyük bir çökmeyle sonuçlanır - potansiyel olarak tek görevli bir sistemde can sıkıcıdır) diğer programlar çalışıyorsa felaket).

Değiştirici

Durum , 512KB veya daha fazla belleğe sahip bir Mac'in aynı anda birden fazla uygulamayı çalıştırmasının bir yolu olan Switcher'ın gelişiyle daha da kötüleşti . Bu, her seferinde bir uygulama yaklaşımını çok sınırlayıcı bulan kullanıcılar için gerekli bir adımdı. Apple artık bellek yönetimi modeline ve mevcut uygulamalarla uyumluluğa bağlı olduğu için, her uygulamanın mevcut RAM'den kendi yığınını tahsis ettiği bir düzen benimsemek zorunda kaldı. Her bir yığına tahsis edilen gerçek RAM miktarı, programcı tarafından belirlenen, her uygulamanın meta verilerine kodlanmış bir değer tarafından belirlendi. Bazen bu değer belirli iş türleri için yeterli değildi, bu nedenle değer ayarının, yığın boyutunu kendi gereksinimlerine uyacak şekilde ayarlamasına izin vermek için kullanıcıya maruz bırakılması gerekiyordu. " İleri düzey kullanıcılar " arasında popüler olsa da , teknik bir uygulama ayrıntısının bu teşhiri, Mac kullanıcı felsefesinin temeline aykırıdır. Kullanıcıları ezoterik tekniklere maruz bırakmanın yanı sıra, daha sonra çoğunu kullanılmadan bıraksa bile tahsis edilen tüm RAM'ini almak için bir uygulama yapılacağından, verimsizdi. Başka bir uygulama belleği yetersiz olabilir, ancak başka bir uygulamanın "sahip olduğu" boş belleği kullanamayabilir.

Bir uygulama, bir kardeş uygulamanın yığınını yararlı bir şekilde kullanamazken, tipik olarak yanlışlıkla saçma bir adrese yazarak onu kesinlikle yok edebilir. Yanlışlıkla bir metin veya görüntü parçasını veya atanmamış bir konumu bir işaretçi olarak ele alan bir uygulama, diğer uygulamaların kod veya verilerinin veya hatta işletim sisteminin üzerine yazabilir ve programdan çıktıktan sonra bile "pusuda" bırakabilir. Bu tür sorunları analiz etmek ve düzeltmek son derece zor olabilir.

Switcher , Sistem 4.2'de MultiFinder'a dönüştü ve Sistem 7'de İşlem Yöneticisi oldu ve o zamana kadar bu plan uzun süre yerleşik hale geldi. Apple, aşikar sınırlamaları aşmak için bazı girişimlerde bulundu - geçici bellek, bir uygulamanın kısa süreler için kendi yığınının dışında kalan boş RAM'i "ödünç alabildiği" biriydi, ancak bu programcılar için popüler değildi, bu nedenle sorunları çözmekte büyük ölçüde başarısız oldu. Apple'ın System 7 Tune-up eklentisi bir "minimum" bellek boyutu ve "tercih edilen" bir boyut ekledi - eğer tercih edilen bellek miktarı mevcut değilse, program minimum alanda, muhtemelen azaltılmış işlevsellikle başlayabilirdi. Bu, Sistem 7.1'den başlayarak standart işletim sistemine dahil edildi, ancak yine de temel sorunu çözmedi.

Kullanılmayan bellek bölümlerini diske sayfalandırarak daha fazla bellek kullanılabilir hale getiren sanal bellek düzenleri, Connectix Virtual gibi üçüncü taraf yardımcı programlar ve ardından Apple tarafından System 7'de kullanılabilir hale getirildi . Bu, Macintosh bellek kapasitesini bir performans maliyetiyle artırdı, ancak korumalı bellek eklemedi veya bellek yöneticisinin bazı işaretçileri geçersiz kılacak yığın sıkıştırmasını engellemedi.

32 bit temiz

Başlangıçta Macintosh, 512 kB limitli 128 kB RAM'e sahipti. Bu, Macintosh Plus'ın piyasaya sürülmesiyle 4 MB'a çıkarıldı . Bu Macintosh bilgisayarlar , 32 bit işlemci olan 68000 CPU kullanıyordu, ancak yalnızca 24 fiziksel adres satırına sahipti. 24 satır, işlemcinin o sırada yeterli bir miktar olarak görülen 16 MB'a kadar belleği (2 24 bayt) adreslemesine izin verdi . Macintosh tasarımındaki RAM sınırı , bellek haritasının yapısı nedeniyle 4 MB RAM ve 4 MB ROM idi . Bu sorun, bellek haritasını Macintosh II ve Macintosh Portable ile değiştirerek 8 MB'a kadar RAM'e izin vererek düzeltildi .

Bellek kıt bir kaynak olduğu için, Mac OS yazarları her adreste kullanılmayan bayttan yararlanmaya karar verdiler. Orijinal Bellek Yöneticisi (Sistem 7'nin gelişine kadar) her 32 bitlik işaretçi ve tutamacın yüksek 8 bitine bayraklar yerleştirdi . Her adres, ana işaretçi tablosunda saklanan "kilitli", "temizlenebilir" veya "kaynak" gibi bayraklar içeriyordu. Gerçek bir adres olarak kullanıldığında, bu bayraklar gizlendi ve CPU tarafından göz ardı edildi.

Çok sınırlı RAM alanının iyi bir şekilde kullanılması, Apple, 32 bit Motorola 68020 CPU kullanan Macintosh II'yi piyasaya sürdüğünde bu tasarım sorunlara neden oldu . 68020, 4 GB (2 32 bayt) belleğe kadar adresleyebilen 32 fiziksel adres hattına sahipti . Bellek Yöneticisinin her işaretçinin ve tutamacının yüksek baytında depoladığı bayraklar artık önemliydi ve adresleme hatalarına yol açabilir.

Teoride, Macintosh sistem yazılımının mimarları bu sorunu önlemek için "yüksek baytta bayrakları" değiştirmekte özgürdü ve yaptılar. Örneğin, Macintosh IIci ve sonraki makinelerde HLock() ve diğer API'ler, yüksek tutamaç bitlerini işaretlemekten başka bir şekilde tutamaç kilitlemeyi uygulamak için yeniden yazılmıştır. Ancak birçok Macintosh uygulama programcısı ve Macintosh sistem yazılım kodunun büyük bir kısmı, bayraklara HLock() , onları işlemek için sağlananlar gibi API'leri kullanmak yerine doğrudan erişti . Bunu yaparak, uygulamalarını gerçek 32 bit adresleme ile uyumsuz hale getirdiler ve bu, "32 bit temiz" olmadığı olarak bilinir hale geldi.

Bu sorundan kaynaklanan sürekli sistem çökmelerini durdurmak için, 68020 veya 68030 üzerinde çalışan Sistem 6 ve önceki sürümler makineyi 24 bit moduna zorlar ve yalnızca ilk 8 megabayt RAM'i tanıyıp ele alır, bu da bariz bir kusurdur. donanımı 128 MB'a kadar RAM kabul edecek şekilde kablolanmış ve ürün literatüründe bu özelliği tanıtan makineler. System 7 ile, Mac sistem yazılımı nihayet 32 ​​bit temizlendi, ancak yine de kirli ROM'lar sorunu vardı. Sorun, 24-bit veya 32-bit adresleme kullanma kararının, ROM rutinleri, NuBus ROM'ların ve disk sürücülerinin yüklendiği temel bir Mac ortamını kurmak için Bellek Yöneticisini başlattığı zaman, önyükleme sürecinde çok erken verilmesi gerektiğiydi. ve idam edildi. Daha eski ROM'larda herhangi bir 32-bit Bellek Yöneticisi desteği yoktu ve bu nedenle 32-bit kipte önyükleme yapmak mümkün değildi. Şaşırtıcı bir şekilde, bu hataya yönelik ilk çözüm , 1991 ürünü MODE32'nin Bellek Yöneticisini yeniden başlattığı ve Mac önyükleme sürecinin ilk bölümlerini tekrarlayan, sistemin 32 bit modunda önyükleme yapmasına ve hepsinin kullanılmasına olanak tanıyan yazılım yardımcı şirketi Connectix tarafından yayınlandı. makinedeki RAM. Apple, yazılımı daha sonra 1991 yılında Connectix'ten lisansladı ve ücretsiz olarak dağıttı. Macintosh IICi ve daha sonra Motorola tabanlı Macintosh bilgisayarları 32 bit temiz ROM'ları vardı.

Uygulamaların tüm 24-bit bağımlılıklarını kaldıracak şekilde güncellenmesi epey bir zaman olmuştu ve System 7, uygulama uyumsuzlukları bulunursa, 24-bit moduna geri dönmenin bir yolunu sağladı. PowerPC ve Sistem 7.1.2'ye geçiş sırasında, yerel uygulamalar oluşturmak için 32 bit temizlik zorunlu hale geldi ve daha sonra Motorola 68040 tabanlı Mac'ler 24 bit modunu destekleyemedi.

Nesne yönelimi

Mac'i programlamak için nesne yönelimli dillerin yükselişi - önce Object Pascal , sonra C ++ - benimsenen bellek modelinde de sorunlara neden oldu. İlk başta, yeniden konumlandırılabilir olma avantajını elde etmek için nesnelerin tutamaçlar aracılığıyla uygulanması doğal görünecektir. Bu diller, başlangıçta tasarlandıkları şekliyle, nesneler için parçalanma sorunlarına yol açacak işaretçiler kullanıyordu. THINK (daha sonra Symantec ) derleyicileri tarafından uygulanan bir çözüm, Handles'ı nesneler için dahili olarak kullanmak, ancak bunlara erişmek için bir işaretçi sözdizimi kullanmaktı. Bu ilk başta iyi bir fikir gibi göründü, ancak kısa süre sonra derin sorunlar ortaya çıktı, çünkü programcılar yer değiştirebilir mi yoksa sabit bir blokla mı uğraştıklarını bilemediler ve bu yüzden nesneleri kilitleme görevini üstlenip üstlenmeyeceklerini bilemeyeceklerdi. Söylemeye gerek yok ki bu, bu erken nesne uygulamalarında çok sayıda hataya ve soruna yol açtı. Daha sonra derleyiciler bunu yapmaya kalkışmadı, ancak gerçek işaretçiler kullandılar, genellikle Mac OS bellek modeli etrafında çalışmak için kendi bellek ayırma şemalarını uyguladılar.

Mac OS bellek modeli, tüm doğal sorunları ile birlikte, ciddi uygulama uyumluluğu kısıtlamaları nedeniyle Mac OS 9'a kadar bu şekilde kalırken , ucuz RAM'in artan kullanılabilirliği, çoğu kullanıcının bir köşe. Hafıza verimli bir şekilde kullanılmadı, ancak konu yeterince kritik hale gelmeyecek kadar boldu. Orijinal tasarımın amacının çok sınırlı miktarda bellek kullanımını en üst düzeye çıkarmak olduğu düşünüldüğünde, bu ironiktir. Mac OS X sonunda modern bir seyrek sanal bellek düzeni uygulayarak tüm şemayı ortadan kaldırdı. Eski bellek modeli API'lerinin bir alt kümesi, Carbon'un bir parçası olarak uyumluluk için hala mevcuttur , ancak altındaki modern bellek yöneticisi (iş parçacığı güvenli bir malloc uygulama) ile eşleşir. Apple önerir Mac OS X kod kullanımını malloc ve free "neredeyse sadece".

Referanslar

Dış bağlantılar