Yan yana
Stack BelleğivsHeap Belleği
Stack ile heap belleği arasındaki fark nedir?
Güncellendi 2 dk okuma6 fark
Kısaca
Stack, çağrıların yerel değişkenlerini LIFO düzeniyle otomatik yönetir, hızlı ama küçüktür; heap ise çalışma zamanı verisini tutar, büyük ama yavaştır.
Stack Belleği
Stack belleği, bir thread'in fonksiyonlarının yerel değişkenlerini ve dönüş adreslerini tuttuğu bölgedir; her çağrıda büyür, dönüşte otomatik olarak küçülür.
Stack Belleği sayfasını okuHeap Belleği
Heap belleği, boyutu ya da ömrü önceden bilinmeyen, çalışma zamanında ayrılan ve onu oluşturan fonksiyondan uzun yaşayabilen verilerin tutulduğu bölgedir.
Heap Belleği sayfasını okuStack Belleği ve Heap Belleği karşılaştırması
| Özellik | Stack Belleği | Heap Belleği |
|---|---|---|
| Ne saklar | Fonksiyon çerçeveleri: yerel değişkenler, parametreler, dönüş adresleri | Çalışma zamanında ayrılan nesneler ve veriler |
| Yönetim | Otomatik, son giren ilk çıkar | Elle, sahiplik kurallarıyla ya da çöp toplamayla |
| Ayırma hızı | Çok hızlı | Daha yavaş |
| Boyut | Küçük, thread başına sabit | Büyük, gerektikçe büyür |
| Ömür | Fonksiyon döndüğünde biter | Serbest bırakılana ya da toplanana kadar |
| Tipik hatalar | Stack overflow | Bellek sızıntıları, use-after-free, parçalanma |
Fark, açıklamalı
Her thread'in bir stack'i vardır. Bir fonksiyon çağrıldığında parametrelerini, yerel değişkenlerini ve dönüş adresini içeren bir çerçeve (frame) eklenir; fonksiyon döndüğünde çerçeve çıkarılır ve bellek yeniden boşalır. Ayırma yalnızca bir işaretçiyi kaydırmak olduğu için son derece hızlıdır, ama stack küçüktür, tipik olarak birkaç megabayt, ve üzerindeki değerler yalnızca fonksiyon kadar yaşar.
Heap ise bütün programın paylaştığı büyük bir havuzdur. Bellek ihtiyaç duyulduğunda istenir; malloc ya da new ile açıkça veya bir dil nesne oluşturduğu her seferde örtük olarak; serbest bırakılana kadar da geçerli kalır. Bu, onu büyük veri, boyutu değişen veri ve onu oluşturan fonksiyondan daha uzun yaşaması gereken veri için doğru yer yapar.
Heap'i yönetmek daha pahalıdır. Bir ayırıcının boş bloklar bulması, neyin kullanıldığını izlemesi ve parçalanmayla başa çıkması gerekir; belleği birinin serbest bırakması da gerekir: C ve C++'ta programcı, Rust'ta derleyicinin sahiplik kuralları, Java, Python, Go ve JavaScript'te bir çöp toplayıcı. Hatalar bellek sızıntılarına, use-after-free hatalarına ya da çöp toplama duraklamalarına yol açar.
Sık yapılan bir yanlış, verinin nereye gideceğini her zaman programcının seçtiğini düşünmektir. C, C++ ve Rust'ta büyük ölçüde siz seçersiniz; Java, Python ve JavaScript gibi dillerde ise nesneler normalde heap'te yaşar ve çalışma ortamı karar verir, bazen kısa ömürlü değerleri optimize edip stack'e koyar. Stack'in tükenmesi de genellikle derin özyinelemeden kaynaklanan bir stack overflow'a yol açar.
Hangisini kullanmalısınız?
Stack Belleği şu durumlarda doğru seçim:
- Veri küçük ve boyutu derleme zamanında biliniyor.
- Yalnızca tek bir fonksiyon çağrısı sırasında gerekiyor.
- Mümkün olan en hızlı ayırmayı istiyorsunuz.
Heap Belleği şu durumlarda doğru seçim:
- Veri büyük ya da boyutu çalışma zamanında değişiyor.
- Onu oluşturan fonksiyondan daha uzun yaşaması gerekiyor.
- Fonksiyonlar ya da thread'ler arasında paylaşılıyor.
Sık sorulan sorular
Stack, heap'ten daha mı hızlı?
Stack'te ayırmak ve serbest bırakmak çok daha hızlıdır, çünkü yalnızca bir işaretçiyi kaydırır. Veriye erişim hızı benzerdir, ama stack verisinin CPU önbelleğinde bulunma olasılığı daha yüksektir.
Stack overflow'a ne yol açar?
Thread'in sahip olduğundan fazla stack alanı kullanmak; en sık çok derin ya da sonsuz özyinelemeyle veya çok büyük yerel diziler tanımlayarak.
Java stack'i mi, heap'i mi kullanır?
İkisini de. Yerel ilkel değerler ve referanslar stack'te yaşar; nesneler ise heap'te yaşar ve çöp toplayıcı tarafından serbest bırakılır.