Windows'da genel olarak bellek konusu sadece fiziksel bellek (RAM) ile sınırlı değildir. Ana kartın bellek yuvalarına takılan RAM ünitelerinden bağımız olarak, çalışan her süreç için geniş bir sanal adres alanı sunulur. 32-bitlik sistemlerde bu 2 GB, yeni 64-bitlik sistemlerde ise bu çok daha fazladır (128 GB gibi). Bu sanal bellek elbette. Her çalışan program 128 GB bellek kullanabilir demek değil.
İşletim sisteminde ise belli bir sınıra kadar çalışan süreçlere bellek tahsisi yapılabilir. Bu sınır da makinedeki RAM ile takas dosyası boyutunun toplamı kadardır. Bu değere kaydetme sınırı (commit limit) denir.
Diyelim ki Word'ü açtık ve uzunca bir belge hazırladık. İçine de bir sürü resim ekledik, tablolar falan... Derken sayfalarca uzunluğunda bir belge oluştu. Bunu yaparken uzun bir süre harcadık. Nihayetinde Word yazdığımız tüm içeriği kaybetmememk için işletim sisteminden sürekli bellek talebinde bulundu, bunları hafızada tuttu. Bunu yaparken de arka planda diyelim ki müzik dinliyorduk, Firefox'ta bir sürü sekme açıktı, ayrıca bir sürü başka program da açıp kapattık, bellek ihtiyacı sadece Word ile sınırlı kalmadı. Bu sürede bilgisayar Word için ayrılan bellek miktarının bir kısmını boşaltarak diğer uygulamalara verir. Ancak Word'ün verilerini de kaybetmemek için onları takas dosyasına yazar. Bu işi yaparken de en eski oluşturulmuş, en uzun süre önce üzerinde işlem yapılmış bellek alanlarını seçer. Word tekrar bu verilere ihtiyaç duyduğu anda ise bu bellek alanı takas dosyasından okunarak tekrar belleğe alnır; muhtemelen başka programların uzun süredir kullanılmayan verilerini yine takas dosyasına kaydederek.
Burada şu ayrımı yapmak gerek; Word ile çalışırken verilerin bir kısmı bellekte tutuluyordu, diğer bir kısmı da takas dosyasında tutuluyordu. Başka programlar için de aynı şey geçerli. Firefox yeni açtığım sekmeye ait verileri bellekte tutarken, ilk açtığım sekmedeki verileri takas dosyasına atmıştı. Bu süreçlerden her biri sanal bellek alanında 2 GB'a kadar (32 bitlik bir sistem olduğunu farzedersek) adresleme yapıyor olabilir, ancak her süreç için bellekte ayrılabilecek o kadar alan olmayabilir. Bu durumda bu 2 GB'lık sanal bellek alanındaki verilerin bir kısmı bellekte değil, takas dosyasında tutuluyor olabilir.
Ayrıca Word bazı sistem özellikerini kullanabilmek için (pencereyi çizebilmek, yapılandırma diyaloglarını görüntüleyebilmek, yazıcıdan çıktı alabilmek vs) bazı sistem dll dosyalarını yükleyecek ve kullanacaktır. Bu veriler diğer süreçlerle paylaşılan bir bellek alanı oluşturur.
Bu noktada bazı bellek terimlerini isimlendirelim:
Çalışma kümesi (working set) : Süreç tarafından işletim sisteminden talep edilen ve henüz bellekte tutulan (takas dosyasına gönderilmemiş) alan ile paylaşılan (dll dosyaları gibi) veriler. Bu alanda hem sürece özel üretilen veriler hem de paylaşılan kodlar depolanır.
Ayırma boyutu (commit size) : Bu ise programa tahsis edilen tüm sanal bellek miktarını gösterir. Bu veriler paylaşılmış veriler değil, diğer süreçler tarafından erişilemeyen, bu süreç tarafından üretilen özel verilerdir. Çalışma kümesinden farklı olarak bu rakama dahil olan bellek alanlarının tümünün RAM'de tutulduğunun garantisi yoktur. Eski verilerin bir kısmı takas dosyasına gönderilmiş olabilir. Bu alanda paylaşılan kodlar depolanmaz.
Yukarıdaki ekran görüntüsünde de notepad.exe sürecinin kullandığı bellek alanını inceleyelim. Bu resimde bellek ile ilgili iki sütun görüntüleniyor; Çalışma Kümesi ve Ayırma Boyutu. Notepad.exe için Çalışma Kümesi sütununda gösterilen 12.744 KB veri doğrudan RAM üzerinde tutulan not defteri verisi. Ancak buna paylaşılmış bellek (dll gibi) de dahil. Ayırma Boyutu sütununda gösterilen rakam ise not defteri tarafından ihtiyaç duyulan tüm veri miktarını gösterir. Bunun bir kısmı takas dosyasında olabilir, ancak bu rakama paylaşılan bellek miktarı dahil değildir.
Bu alanlara ek olarak Windows 7 ve sonrası sürümlerde gelen "Özel Çalışma Kümesi" alanı var. Bu alana paylaşılan bellek miktarı dahil değil. RAM'de saklanan sürecin özel verilerini gösteriyor. Bu alanı görebilmek için menüden Görünüm>Sütun Seç ile Bellek-Özel Çalışma Kümesi'ne ait kutuya işaret koymamız gerek.
Görüldüğü gibi not defteri için (seçili satır) özel çalışma kümesi de 7.948 KB. Çalışma Kümesi alanından bu veriyi çıkartarak 4.797 KB'lık veri paylaşılan bellek miktarı oluyor. Not defterin ayrılan toplamda 8.216 KB'lık verinin ne kadarı takas dosyasına atılmış olabilir? 8.216'dan 7.948'i çıkararak bulabileceğimiz 268 KB da "muhtemelen" takas dosyasına atılan miktar olabilir. Muhtemelen diyorum, çünkü süreçlere ait uzun süredir kullanılmayan alanlar hemen takas dosyasına gönderilmez. Bir süre daha belleğin bekleme alanında bekletilir, tekrar ihtiyaç duyulma ihtimaline karşı. Bir süre sonraki durak elbette takas dosyası olacaktır.
Bellekteki bu işlemler "sayfa" denen 4 KB'lık bölümler üzerinden yapılır. Tüm bellek 4 KB'lık sayfalara bölünmüştür. Süreç, işletim sisteminden her yeni bellek talep ettiğinde bu sayfaların katı miktarda alan tahsis edilir. Bellekten takas dosyasına veya tam tersi yöndeki taşıma işlemlerinin tümü bu 4 KB'lık sayfa boyutu üzerinden yapılır. Bellekte en uzun süredir kullanılmayan alanlar yine bu sayfa boyutları üzerinden belirlenir. Yani 1 byte'lık bir alan bile talep edilse 4 KB'lık bir sayfa ayrılır. Bu sebeple yukarıdaki bellek verilerinin tümü 4'e bölünebilen sayılardır.
Bir sürecin erişmek istediği veri doğrudan çalışma kümesi içindeyse o verilere doğrudan erişir, veriler veya kodlar farketmez. Ancak veriler ayırma boyutu alanına taşınmışsa onlara doğrudan erişemeyecek, erişim bir sayfa hatasına (page fault) sebep olacaktır. Söz konusu sayfa henüz bekleme alanındaysa (standby memory) bu bir yazılımsal sayfa hatası (soft page fault), aksi takdirde veri takas dosyasına gönderildiyse bir donanımsal sayfa hatasına (hard page fault) sebep olur. Görüldüğü gibi sayfa hatalarının aslında bir hatayla ilgisi yok, tamamen normal bir işleyiş.
Örneğin Word ile hazırladığımız belgenin yazıcıdan çıktısını almak istiyoruz. Menüden yazdır komutunu verdikten sonra sistem yazıcı ile ilgili sistem dosyalarına ihtiyaç duyacaktır. Bu sistem dosyaları bilgisayar açıldığından beri hiç kullanılmadıysa (veya kullanıldıysa ama üzerinden yeteri kadar uzun bir süre geçtiyse ve artık hafızada değillerse) bir donanımsal sayfa hatası oluşur. Veriler diskten okunur, işlevlerin kullanılabilmesi için gereken yordamlar belleğe alınır. Bu miktar çalışma kümesi alanına eklenir. Aradan bir süre geçtikten sonra bu sistem dosyaları için ayrılan alan önce bekleme alanına gider. Tam bu anda tekrar çıktı almak istersek bu sistem dosyalarına yapılan referans için bir yazılımsal sayfa hatası oluşur, diske hiç ihtiyaç duyulmadan işlem tamamlanır. Ama yeteri kadar uzun süre geçtikten sonra tekrar çıktı almak istersek bu bir donanımsal sayfa hatası oluşur. Veriler tekrar diskten okunur. Ama bu veriler paylaşılan sistem dosyalarına ait olduğu için hiçbir zaman takas dosyasına yazılmaz, doğrudan diskten tekrar okunur.
Windows sanal bellek miktarı üzerindek çalışan bir işletim sistemi olduğundan, her bir sürece yapılan sanal bellek atamalarının (ayırma boyutu / committed bytes) toplamı ile çekirdek (kernel) işlemleri için yapılan bellek ayırmaların sayfalanmış (paged) miktarının toplamı sistem toplam kaydetme miktarı (commit charge) ile ifade edilir. Eğer bu miktar sistem ayırma sınırına (system commit limit, yukarıda açıkladığım gibi sistem RAM'i ile takas dosyasının boytunun toplamı) ulaşırsa bellek problemi uyarıları ile karşılaşırız. Takas dosyası otomatik olarak (eğer öyle ayarlandıysa) büyütülmeye çalışılır. Çok nadir de olsa bu gibi durumlarla karşılaşıldığında hangi sürecin bu durumda aşırı bellek kullandığını incelemek gerekebilir.
Çok uzun oldu. Evet, anlaşılması da kolay olmadı, Türkçe terimleri de işin içine katınca. Üzgünüm.
Ek 2022-07-15 : Process Explorer ayırma boyutu (commit size) yerine private bytes terimini kullanıyor. Özet olarak bu veri, program için ayrılan tüm sanal bellek miktarını gösteriyor. Bunun RAM'de tutulan bölümü private working set ile gösterilen miktarı. Workins set ise bu değere paylaşılan bellek miktarını ekleyince ortaya çıkıyor. Nihayetinde bir sürecin işletim sisteminden ne kadar bellek ataması aldığını öğrenmek için private bytes alanına bakmak gerek.
Ayrıca Powershell'de Get-Process cmdlet'inin çıktıları arasında Private Working Set alanı yoktur. Bunu görmek için performans sayaçlarına bakmak gerek.
Hiç yorum yok:
Yorum Gönder