Değer ve Referans Tipleri

Bellek bölgeleri: Stack ve Heap nedir? Değer ve referans tip nedir ve aralarındaki farklar nelerdir? Derleme Zamanı nedir? Çalışma Zamanı nedir?

Sırrı KÖMÜR
Kodcular
4 min readOct 10, 2022

--

Photo by Radu Marcusu on Unsplash

Bellek, kitaplığa benzer. Kitaplarınızı renklerine, cildine, konusuna veya alanına göre sınıflandırırız. Değer ve referans tipte, aynı şekilde, kitaplığa kitaplarımızı dizmek gibidir. Kimini yığarız, kimini istifleriz. Hadi gelin, birlikte kitaplığımızı düzelim…

Değer ve referans tipi konusuna geçmeden evvel stack ve heap bellek bölgelerine göz atalım.

Bellek Bölgeleri: Stack ve Heap

Stack (İstif)

Statik verilerin tutulduğu bellek bölgesidir. Burada tek bir değer tutulur. Bu değerler, adres de olabilir tekil veri de. Stack işlemleri, derleme zamanında yapılır. Bu ne demektir?

Derleme zamanı (Compile time), yazdığımız kodların (Java, C#, Python, vs.) bilgisayarın anlayıp çalıştırabileceği koda çevrildiği zaman dilimidir. Dolayısıyla bilgisayara hangi bellek adresinde çalışacağını göstermesi öncelikli olarak bu adımda gerçekleşir. Programın, bilgisayar tarafından çalıştırıldığı anda ise Çalışma Zamanı Stack’i devreye girer. Böylelikle referanslar değiştiği takdirde program çalışmaya devam edebilir.

Heap (Yığın)

Dinamik verilerin tutulduğu bellek bölgesidir. Burada bir türe özgü, birden çok değer tutulabilir. Bu değerlere erişim, referans noktalarının işaretleri ile mümkündür. Burada bellek bölgesinin adresini bilmeniz şarttır. Dolayısıyla stack bölgesinden daha karmaşıktır.

Stack (İstif), adından da anlaşılacağı gibi düzen içindedir. İlk giren, son çıkar (LIFO). Ancak heap böyle değildir. Heap (Yığın), düzenli değildir. Aralarında boşluklar olabilir. Belleğin herhangi bir bölgesinde işlem gerçekleştirilebilir. Heap işlemleri, Çalışma Zamanında yapılır. Peki, bu ne demektir?

Artık, yazılan kodlar, makine kodlarına çevrilmiştir. Böylece bilgisayar/makine, kendi donanımına, kodların buyurduğu şekilde çalışması için emir verir. Donanım süreci çalışmaya başlar başlamaz, çalışma zamanı devreye girer. Bağlantılar silsilesi gerçekleşmiş olur.

Değer ve Referans Tip

Bir değişken, hem bir değer hem de değerler nesnesini tutabilir. Bu durumları Değer ve Referans Tip adı altında sınıflandırırız. Hadi gelin bunlara bir göz atalım.

Değer Tip

Değer tip, stack bellek bölgesinde tutulur. Bu tipin değişkenleri de stack bölgesinde tutulur. Yazılan dilin kuralları bu noktada çok önemlidir. Çünkü değer tipleri, derleme zamanında belirlenir. Bu itibarla, dilin sentaks/söz dizimi bu noktada kontrol edilir. Derleme anındanki hatalar, söz dizimi dolayısıyla gerçekleşir.

Derleme zamanında, çöp toplayıcı (Garbage Collector) stack’e erişemez (Çöp toplayıcı; Java, C#, vs. gibi yüksek seviyeli dillerde bulunmaktadır.). Bu durum stack bölgesinde bulunan değerlerin silinmesinin manuel olarak gerçekleştirilebileceği anlamına gelir.

Değer tipler nelerdir?

  • Tüm sayısal veri tipleri (int, float, double, short, long, byte, vs.)
  • Boolean
  • Char

Referans Tip

Stack bölgesinde belirtilen, adres referansının işaret ettiği değerler, heap bölgesinde tutulur. Değerler/değişkenler, işaretçi adres aracılığıyla gösterildiği için Referans Tip adını almıştır. Yönlendirme mantığı ile çalışır.

Heap bölgesindeki bir alan, stack bölgesinden işaret edilmiyorsa bu alan, Çöp Toplayıcı (Garbage Collector) aracılığıyla silinir/çöpe atılır. Çöp toplayıcı, çalışma zamanında bazı bellek bölgelerine erişebilir. Değer tipin aksine, referans tipteki değerler çalışma anında silinebilir.

Referans tipler nelerdir?

  • String
  • Tüm diziler (Arrays)
  • Class
  • Delegate’ler (C#’ta var, Java’da yok!)

Örnek: Stack ve Heap

Stack bölgesinde iki alan düşünelim. Bu alanların her ikisi de heap bölgesindeki farklı iki alanı, dolayısıyla farklı iki değeri gösteriyor. Stack bölgesindeki bir alanın diğer alanın işaret ettiği heap alanındaki değerlere erişmesini istiyoruz. Bu durumda stack alanının, istenen heap alanına referans vermesi gerekir. Ancak burada çok kritik bir nokta mevcuttur. Bizler burada heap alanındaki değişkeni/değerleri kopyalamıyoruz. Yalnızca referans veriyoruz. Nihayetinde, gezen çöp toplayıcı heap bölgesinde, stack bölgesinden işaret edilmeyen bir alan buluyor ve onu çöp sepetine atıyor.

Bu betimi, resmedelim:

Birinci grafikte integer veri tipinin yalnızca stack bölgesinde yer aldığını görüyoruz. Buna rağmen string veri tipinin ise heap bölgesine referans verilerek depolandığını görüyoruz. Bunun sebebi integer bir değer tiptir. String ise referans tiptir. Aklınıza: “Neden string, değer tip değildir?” sorusu gelmiş olabilir. String, aslında karakterlerden oluşan bir dizidir. Programcı dili ile söylenirse “Char Array” olarak adlandırılır. Dolayısıyla diziler, referans tiptir.

Grafik 1: Bellek Ayırma

name2 isimli değişkenin adres referansına, name1 isimli değişkenin adresinin referansını veriyoruz (Bu işlem stack bölgesinde gerçekleşiyor.). Böylelikle name2'nin heap bölgesindeki değeri “Can KÖMÜR” yerine “Sırrı KÖMÜR” olarak değişiyor. Zira biz, “Sırrı KÖMÜR” değerinin adresini atadık/kopyaladık. Grafikte dikkat edilmelidir ki stack bölgesinde name2 değişkenine referans veren adres kopyalanmıştır, değeri değil!

Grafik 2: Referans Kopyalaması ve Çöp Toplayıcı (Garbage Collector)

Örnek Uygulamalar

Bizler programlama yaparken birbirinin alternatifi olan durumlar için referansları kullanırız. Bu durum kod karmaşıklığını, hataları azaltırken yazılımın sürdürülebilirliğini arttırmaktadır.

Örnek: Değer tip

Değer tiplerin, değerleri ile birlikte stack bölgesinde tutulduğunu söylemiştik. Bu durumu göz önünde alırsak, farklı herhangi bir değer tipteki değişkeni atadığımızda, adresler değil barındırdığı değerler kopyalanır. Aşağıdaki örnek bu durumu açıklamaktadır.

Örnek: Referans tip

Referans tipler, stack bölgesindeki alanların işaretlediği heap alanlarında tutulur. Aşağıdaki örnek ile daha net açıklayalım.

numbers1 değişkenini, numbers2 değişkenine kopyaladık. Ancak buradaki kopyalama işlemi değer tipte olduğu gibi stack ile sınırlıdır. Bu itibarla referans tipin stack bölgesinde bulunan değeri, heap bölgesindeki değerinin referans adresidir. Bu durumu göz önünde bulundurursak numbers1'e aslında numbers2'nin heap bölgesindeki referans adresi kopyalanmış oldu. Böylelikle numbers2 değeri numbers1 ile aynı heap alanını göstermiş olur. Bu durumu fark eden çöp toplayıcı (garbage collector), eskiden numbers2'nin gösterdiği alanın, artık kimsenin göstermediğini görünce bu alanı temizler.

Bu durumun programlamada en çok ve en güzel kullanım alanı interface’lerdir. Sonraki yazım bunun üzerine olacaktır. Görüşmek üzere…

Öğrenmek ve öğretmek için çıktığım bu yolculukta, yazımı alkışlayarak bana destek olabilir misin?

Medium bizlere, her gönderi için 50 alkışa (clapping) kadar izin veriyor. Yazarlara destek olmak için beğendiğiniz kadar alkış atabilirsiniz.

--

--