Bir programın çalışmaya başlama ve devam etme sürecinde CPU ve RAM cephesinde bazı operasyonlar gerçekleşir. Program belleğe yüklendiğinde belleğin segment adı verilen üç farklı alanına yayılır:
Bir programın çalışmaya başlama ve devam etme sürecinde CPU ve RAM cephesinde bazı operasyonlar gerçekleşir. Program belleğe yüklendiğinde belleğin segment adı verilen üç farklı alanına yayılır:
. Code Segment (Programın kod alanı)
. Stack (Yığın)
. Heap
Text Segment olarak ta bilinen Code Segment, programa ait makine kodunu yani programın CPU’ya göndereceği komutları tutar. Programımızın içerisinde basit bir tamsayı türünden nesnenin tipik olarak çalışma zamanında yüklendiği yer RAMin stack dediğimiz bölgeleridir. Stack bölgelerine Mikroişlemcilerde bulunan Stack Pointer vasıtası ile doğrudan erişilebilir. Stack Pointer o anda bellekte çalışılan bölgenin adresini tutan yapıdır. Stack pointer, bellekteki alan tahsisatına göre bir azaltılır yada bir artırılır. Bu yüzden stack bölgesinde tutulacak verilerin çalışma zamanı öncesi ne kadarlık bir alan kapladığının bilinmesi gerekir. Aksi bir durumda Stack Pointer işlevi ile çelişkili bir durum olurdu. .NET platformunun altyapısını oluşturan JIT derleyicilerininde programı yüklediğinde Stack Pointer ı doğru konumlandırmak için tahsisatını yapacağı verinin tam boyutunu bilmesi gerekir.
Bellekteki verilere ulaşmak için CPU tarafında register denen lokasyonlar kullanılır. İşlemci çekirdeğine gömülü özel bellek birimi olarak düşünebileceğimiz register alanları, genel olarak matematiksel işlemler ve bellekteki verilere ulaşma işlemlerini gerçekleştirir. Konumuzla ilgili olanlar, Code Segment (CS) ve Data Segment (DS) registerleridir. Bir program yüklendiği zaman işletim sistemi, programdaki komut ve değişkenleri belleğe yükler ve ilgili segmentlerin adreslerini bahsi geçen registerlere aktararak programın ilk komutu ile işlemi programa bırakır.
Yığın (Stack) alanı, işlemci tarafından verilerin geçici olarak saklandığı veya uygulamanın kullandığı değişkenlerin tutulduğu ve büyüklüğü işletim sistemine göre değişen bellek bölgesidir.
Yığının büyüklüğü, yönetimi, programcının değil uygulamanın sorumluluğundadır. Derleyici veya çalıştırma ortamı, program içindeki değişkenleri ve uzunluklarını tarar ve yığın üzerinde ona göre ayırım yaparak yerleştirir. Bu yüzden derleyici, programı oluşturmadan önce yığın üzerinde oluşturulacak verilerin boyut ve ömürlerini bilmek zorundadır. Bir değişkenin hangi bellek bölgesine kaydedileceğini CPU üzerindeki Stack Pointer (SP) denen register belirler. SP, yığın alanının en üst kısmının yani belleğin o anki uygun yerinin adresini gösterir. Depolanacak verilerin eklenmesi veya silinmesiyle SP değeri bir azaltılır veya artırılır. Bütün verilere eğer stack bölgesinde tahsisat yapılmış olsaydı programlarımızın esnekliği azalırdı, zira C# ta bazı nesneler referans yolu ile belirtildikleri için verinin kendisi stack ta bulunmayabilir.
Bu bellek biriminin yığın olarak anılması, LIFO (Son giren ilk çıkar, Last-In First-Out) ilkesine göre çalışmasından kaynaklanmaktadır. CPU tarafından verilerin yığın alanına konulması, Push, alandan alınması, Pop olarak tanımlanır. Bu ekleme ve çıkarma işlemlerinde bellek adresleri değişmez bunun yerine yığın işaretçisi (stack pointer), aşağı yukarı hareket ettirilerek ilgili veriye erişilir veya yeni veri eklenir. Yığın, dinamik değişkenleri saklamanın yanında, yordam çağrıları yaparken, geri dönüş adresini saklamak, yerel değişkenleri depolamak, yordamlara parametre yollamak için de kullanılır.
Yığın bellek alanı, program çalışmaya başladığı anda belirlenir ve daha sonra bu alanın boyutu değiştirilemez. Bu alan, işletim sistemi tarafından genellikle kısıtlı şekilde belirlendiği için yığın üzerindeki yoğun ekleme işlemlerinde hafıza birimi taşması sorunu yaşanabilmektedir. Stackoverflow sitesi de tam da bu sorun üzerine kurulmuş bir sitedir. Dolayısıyla yazacağımız programlarda stack bölgesinin yönetiminde ne kadar bilgili olursak, o kadar az sorun yaşarız.
Heap:
Stack bölgelerinde olduğu gibi heap alanlarıda RAM da bulunan hafıza alanlarıdır. Bütün C# nesneleri bu bölgede oluşturulur. Stack ten farklı olarak Heap bölgesinde tahsisatı yapılacak nesnenin derleyici tarafından bilinmesi zorunlu değildir. Bu yüzden, heap bölgesini kullanmak programlarımıza büyük esneklik katmaktadır. Genellikle ne kadar yer kaplayacağı belli olmayan değişkenlerin (nesnelerin) veya büyük verilerin geçici olarak saklanması için kullanılır. Yığın bölgesinin tersine çalıştırma ortamı (JIT), heap alanında ne kadar yer kullanılacağını bilmek zorunda değildir.
New anahtar sözcüğüyle bir nesne oluşturduğumuzda JIT, bu nesne için heap üzerinde yer tahsis eder. İşimiz bitince heap üzerindeki nesnelerimizi sildiğimizde heap biriminin o bölgesini boşaltmış oluruz. Böylece yeni değişkenleri o bölgede saklayabiliriz. Heap alanı, program, bellek üzerinde açık olduğu sürece yaşamaya devam eder. Bu yüzden genel (global) ve statik (static) değişkenler bu alan içinde tutulur. Heap alanının okunması veya yazması yığın(stack) alanı kadar hızlı değildir.
Kısacası, stack, programda tanımlanan sabit uzunluklu değişkenler için tahsis edilmiş bellek birimidir. Heap ise programın kullanımı için tahsis edilmiş genel amaçlı bellek birimidir.