Heap ve Stack Bellek Nedir?

Kerim Şentürk
4 min readSep 13, 2022

--

Bilgisayar bilimlerinin en çok karmaşıklık yaşanan kavram çiftlerinden Heap ve Stack özellikle bu alanda yavaş yavaş ilerlemeye başlayanlar tarafından çok sorulan ve anlaşılmasında güçlük yaşanan kavramlardır.

Bir Bilgisayar Mühendisliği öğrencisi olarak kendim de öğrenirken çok fazla farklı kaynaktan araştırma yapmam gerekti.Şunun farkına vardım ki Heap ve Stack’in genel bir yapısı olmasına karşın kullandığımız dile göre işleyişlerinde küçük farklılıklar gösterebiliyor.Bu yüzden “Bunlar kesinlikle Stack’de bunlar kesinlikle Heap’de saklanır” demek her zaman doğru olmayacaktır.Bundan dolayı bu kavramları anlamak için tek bir programlama dili üzerinden önce genel yapısını öğrenerek sonrasında dilleri arasında ne gibi farklılıklar yaşanıyor incelemek gereklidir.Neyse uzatmadan konuya geçelim.

Heap ve Stack Nedir?

Bilgisayarda geçici hafıza olarak adlandırdığımız RAM’in sınırlı ve çok hızlı yapısını efektif bir şekilde kullanmak için oluşturulan mantıksal yapılardır Heap ve Stack.Heap ve Stack statik ve dinamik olması bakımından birbirinden ayrılır.

Stack

Statik boyutlu verileri tutan bölümdür.Yani RAM üzerinde ayrılması gereken alan default olarak bilinen veriler bu alanda saklanır.Bu tipteki verilere “değer tipli” (value type) veriler denir.Örneğin; int, uint, long, boolean, char, float, double, decimal … Fark ettiğiniz gibi bunlar hep ilkel(primitive) tipteki verilerdir. Çünkü bu tipteki verilerin boyutu compiler tarafından default olarak belirlidir ve Stack üzerinde daima sabit boyut ayrılır.Örneğin; int 4 byte yer kaplıyorsa bir int değişken tanımladığımızda bellekte 4 byte yer ayrılır ve bu boyut hiç bir şekilde değişmez.

Değer tipli bu verilerin referansı, veri tipi ve değeri Stack üzerinde aşağıdaki gibi saklanır:

Heap

Dinamik boyutlu verileri tutan bellek bölümüdür.Yani RAM üzerinde boyutu default olarak bilinmeyen verilerin tutulduğu alandır.Örneğin;string, array, list, class, ,interface, object… Bu tipteki verilere “Referans Tipli” (Reference Type) veriler denir. Fark edeceğiniz gibi bunlar ilkel olmayan (none-primitive) veri tipleridir.

Bir string değişken tanımladığımızda bu değişkenin boyutu string’in uzunluğuna göre değişir.Ya da bir list tanımladığımızda list üzerinde eleman ekleyebilir veya çıkartabiliriz.Bu yüzden bu veri tiplerinin boyutunu compiler default olarak bilemez.

Aslında referans tipli veriler sadece heap üzerinden erişilemezler.Adından da anlaşılabileceği gibi bu verileri gösteren bir referans olması gerekir.Tam burada da Stack devreye giriyor.Referans tipli verilerin değeri Heap üzerinde tutulurken referansı ve veri tipi Stack üzerinde tutulur.Hadi bir görselle görelim:

Görüldüğü gibi Heap üzerinde saklanan bir veriye erişmek için Stack’deki referansı kullanmamız gerekmektedir.Tam bu noktada yaşanılan bir karmaşıklık vardır:

Heap üzerinde saklanan aynı tipteki değişkenleri birbirine assign edersek (atama işlemi yaparsak) bu değişkenlerin değerleri değil referansları birbirine aktarılır.Yani birinci değişken Heap üzerindeki 1111 adresini gösteriyorsa ikinci değişken de aynı adresi göstermeye başlar.Bunda dolayı bu atama işleminden sonra iki değişkenden herhangi birinde bir değişiklik yaptığımızda diğer değişken de bundan etkilenir.Hadi daha iyi anlamak için kod ve görselle açıklayalım:

Kod Örneği 1.1
Kod Çıktısı 1.1

Gördüğünüz gibi son a[2]’ye 1000 değerinin atmamıza rağmen b[2]’de 1000 değerini aldı.Stack ve Heap üzerindeki olaylar bu durumu aşağıdaki şekilde açıklıyor:

int[] a={9,10,11};
int[] b={12,13,14}; işlemi
b=a; işlemi
a[2]=1000; işlemi

Gördüğünüz gibi iki değişken de Heap üzerined aynı yeri göstermektedir.Peki ilk başta b dizisi olarak tanımladığımız artık referansı olmaya değere ne olur?İşte bu noktada kullandığımız programlama diline göre yapmamız gerekn işler olabilir.Eğer C veya C++ gibi düşük seviyeli diller kullanıyorsak bu değerleri kendimiz deallocate etmemiz gerekmektedir.Aksi takdirde “Heap Overflow” hatası ile karşılaşırız.C# ve Java gibi daha yüksek seviyeli dillerde bu deallocate işlemini “Garbage Collector” bir diğer adıyla “Çöp Toplayıcı” mekanizması yapar.Ona da bir başka yazımızda değiniriz.

Yazımızı bitirmeden önce hadi son olarak Heap ve Stack arasındaki genel farklılıkları listeleyelim.

→STACK

  • Bellek üzerinde linear bir yapıda verileri yerleştirir.Örneğin 1 byte’lık bir veri 100. adreste saklanıyorsa ondan sonra gelecek 1 byte’lık veri 101. adreste saklanır.
  • Linear yapıda olduğu için verileri erişim hızlıdır.
  • Heap’e göre daha küçük boyutludur.Bu yüzden kod yazarken Stack belleği efektif kullanmak önemlidir.Aksi takdirde büyük uygulamalarda meşhur “Stackoverflow” hatası ile karşılaşmamız muhtemeldir.
  • Statik boyutlu veriler tutulur.int,bool,char,short…

→HEAP

  • Veriler heap bellek üzerinde rastgele yerleşir.Sıralı yapıda değildir.
  • Rastgele yapıda olduğu için değelere erişim yavaş ve maliyetlidir.
  • Stack’e göre daha büyük boyutludur.Ancak referanssız değerleri deallocate etmek gereklidir.Aksi takdirde “OutofMemory” hatasıyla karşılaşabiliriz.
  • Değişken boyutlu veriler tutulur.String,Array,List,Class,interface…

Bir başka yazıda görüşmek üzere ..:D

--

--

Kerim Şentürk

Merhaba ben Kerim. Backend Web Developer olarak Java, Spring araçlarıyla çalışıyorum. Araştırıyor ,öğreniyor ve olabildiğince aktarıyorum. İyi okumalar dilerim.