4 Nisan 2012 Çarşamba

Yeni yazılar

Kalan iki virtual memory yazısından önce araya bir kaç network yazısı sıkıştırmak istiyorum. Elimdekilerden bir ya da ikisini seçip yayınlanabilir hale getireceğim.

Bir de Blogger'ın kod görüntülemek için ayrı bir stili yok sanırım. Bu temada da kodlar çok kötü çıkıyor. Ya temayı değiştireceğim ya da biraz CSS yazacağım.

Ya da uğraşmayıp Wordpress.com'a da geçebilirim.

Virtual Memory nedir? - II - free()

alloc() sülalesi komutların tersi olan free() komutunu kullandığımızda memory managera aldığımız alanların boşa çıktığını söyleriz. Bu durumda Windows ile Linux'un davranışları biraz farklılık gösteriyor. Örnek için aşağıdaki kodu kullanabiliriz. Derlediğimizde program karakter girişi aldığında 1024 pagelik bir alanı doldurur, tekrar karakter girişi aldığında boşaltır.
#define PAGECOUNT 1024 //1024 tane 1024 int dolduracagiz = 1024 sayfa
#define LISTCOUNT 1024

int j=0;
int i=0;
char c;
int *chunklist[PAGECOUNT]; //int 4 byte oldugundan 1024 sayfalik alan
//bu pointer dizisinin kendisi de stackte 1 sayfa tutuyor

//lowmem pointerlardan higmem pointerlara dogru gidiyoruz.
//heap grows upwards.  
printf("ENTER'a basinca 1024 page doldurulacak.\n");
getchar();
while(i<PAGECOUNT) {
 chunklist[i]=(int *) calloc(1024,sizeof(int)); //1 page yer ayır
 for(j=0;j<LISTCOUNT;j++) { // ayrilan alan içinde 1 page boyutunda int array oluştur.
  int *p = chunklist[i];
  p[j]=j;
 }
 i++;
}

printf("Toplam 1024 page dolduruldu.\n1024 page bosaltmak icin ENTER'a basin...\n",i);
getchar();

while(i>1) {
 free(chunklist[--i]);
}
printf("Tum sayfalar bosaltildi.\nCikmak icin ENTER'a basin\n");
getchar();
Programı derleyip Linux altında çalıştırdığımızı düşünelim. İlk açtığımızda tuşa basmadan PID'sini öğrenip
cat /proc/$PID/status | grep VmData
dersek heapin kullandığı alanı görebiliriz. Bellek talep edip doldurduktan ve boşalttıktan sonra da processin status bilgisine baktığımızda 4 MB civarı alanın dolduğunu ve boşaldığını görebiliriz. Bu sayı her zaman page boyutuna bölünebilir, page boyutuna bölersek processin bu iş için kullandığı page sayısına erişiriz. (Doğrudan sayfa sayılarını görmek isterseniz /proc/$PID/statm'e bakın.)

Virtual Memory nedir? - II - segfault

Bir önceki yazıda uygulamaların gerçek memory adreslerinden haberdar olmadığını, her bir uygulamanın sürekli ve adresleyebileceği en büyük memory alanında çalıştığını sandığını söylemiştik. Şimdi memory managera inanan uygulamaların nasıl hatalar yapabileceğine bakalım.

Başlamadan önce bir bilgilendirme; yazıda bol bol stack ve heap kelimelerini kullandım. Executableların bölümlerini anlatan ayrı bir yazı yazacağım ama basit olarak stacki fonksiyonların içinde doğrudan tanımladığınız değişkenlerin tutulduğu, heapi de malloc ile dinamik olarak bellek isteyip kullandığınız alanlar olarak düşünebilirsiniz. Stackin boyutu sınırlı olduğundan alloc() tipi komutları hiç kullanmadan büyük işler yapmaya kalkarsanız segfault ile karşılaşmanız kaçınılmazdır.

Segfault 1 


C'yi yeni öğrenirken sık yapılan hatalardandır, &'ler *'lar karışır, unutulur.

Pointer oluştururken değişkenin adının önüne & koymayı unuttuğumuz şöyle bir kod düşünelim:
 int x=5;
 int *p=x;  //int *p = &x; olacakti
 
 printf("pointerin tuttugu adres %x \n", p);
 printf("pointerin adresindeki deger %d \n");


Bu durumda zaten kodu derlerken compiler bir hata ya da uyarı verir. 

Eğer programı derleyebildiysek programı çalıştırdığımızda hata ile karşılaşırız. Neden? Çünkü x'in adresine değil, 0x5 adresine gidip bir değere ulaşmaya çalıştık. İkinci printf'i kaldırın; sorun yok.

Hata taa CPU üzerindeki MMU'dan geliyor ve işletim sisteminin uygulamayı durdurmasına yol açıyor. Process 5 adresine ulaşmak istediğinde memory manager bu processin kullandığı sayfalar içinde 0x5 adresinin bulunduğu sayfanın gerçek adresine öğrenmeye çalışıyor, MMU ise bu processe 0x5 adresini içeren bir sayfa vermediğini söyleyerek exception gönderiyor.

MSVC 2010 yukarıdaki kodu derlemeye izin vermediği için daha genel bir örnek verelim.

Virtual Memory nedir? - I


Virtual memory hem C programlamada hem de sistem yöneticiliğinde muhattap olduğumuz bir konu. Virtual memory'nin çalışma prensiplerini bilmek bazı durumlarda yazılan uygulamanın ya da genel olarak sistemin verimli çalışması için çok önemli olabiliyor.

Temelde virtual memorynin yaptığı iki iş var:
  1. Processlere kendilerine ait sürekli bir hafıza alanını kullanıyorlarmış gibi hissettirmek
  2. Pagefile/swap kullanarak aktif olmayan uygulamaların fiziksel RAM'i gereksiz yere işgal etmesini engellemek
Virtual memory'den bahsetmeden önce bazı kavramları bir kaç cümle ile açıklamakta fayda var.