Merhabalar, @slowbaskan123 isteğiyle C dili için anlatmış olduğum bu konuyu sizlere C# dilinde de anlatacağım. Konumuz Dinamik Bellek Tahsisi, temel bir şekilde olayın üstünden geçeceğiz. Tam bir anlatım bulunmayacak. Hiç bilmeyenler için temel seviyede anlatacağım. Dinamik bellek tahsisi, programımızın çalışması sırasında ihtiyaç duyduğu bellek miktarını esnek bir şekilde ayarlayabilmemizi sağlar, örnek verecek olursam. Elinizde bir ütü olduğunu düşünün, bu ütünün satıcısı sizsiniz ve bunu kargolayacaksınız. Ayrıca elinizde bir buzdolabı daha var bunu da kargolayacaksınız, bu ikisi için kolaylık olsun diye ikisini de aynı koliye koyup kargolarsanız müşteri zannımca sizin hakkınızda pek iyi şeyler düşünmeyecektir değil mi
İşte dinamik bellek tahsisi de programımızda verilerimizi gerektirdiği büyüklükte bir bellekte kullanmamızı sağlıyor.
C#’ta Garbage Collector sayesinde belleği manuel olarak serbest bırakmak zorunda kalmayız. Bunu siz eklemek zorunda değilsiniz uygulama kendi kendine yapmakta.
1. new: Dinamik bellek tahsisi yaparken kullanılır. `new` anahtar kelimesiyle bellekte bir nesne veya dizi için alan ayırırız.
2. List<T>: Dinamik diziler oluşturmak için kullanılan generic bir koleksiyon sınıfıdır. `List<T>` sınıfı, eleman sayısına göre bellekte dinamik olarak genişleyebilir veya daralabilir. Kısacası lastik gibidir
3. ArrayList: Generic olmayan dinamik koleksiyon sınıfıdır. Farklı türde veriler eklemeye imkan tanır, ancak generic olmadığı için `List<T>` kadar performanslı değildir.
4. Dictionary<TKey, TValue>: Anahtar-değer (key-value) çiftleri şeklinde verileri saklayan bir koleksiyon sınıfıdır. Bu yapılar da dinamik olarak bellekte genişleyebilir. Mesela şehirleri plakalarla eşleştiren bir kod yazıyoruz, buradaki sınıf aşağıdaki şekilde tanımlanmalı.
5. Stack ve Queue: LIFO (Last In, First Out) ve FIFO (First In, First Out) prensiplerine göre çalışan dinamik koleksiyon yapılarıdır. İhtiyaca göre bellekten dinamik olarak yer ayırabilirler.
6. LinkedList<T>: Dinamik bellek kullanımını gösteren veri yapılarından biridir. Bağlı liste yapısı olduğundan bellekte dinamik olarak veri ekleyip çıkarma işlemlerinde avantaj sağlar.
7. HashSet<T>: Benzersiz elemanlardan oluşan dinamik bir koleksiyon yapısıdır. Bu yapı da dinamik olarak bellekten alan ayırabilir.
Konu bu kadar, kolay gelsin.
1. Statik ve Dinamik Bellek Tahsisi Nedir?
Öncelikle, belleği nasıl kullandığımızı anlamamız lazım. Bellek tahsisini iki ana başlıkta inceleyebiliriz: statik ve dinamik bellek tahsisi.- Statik Bellek Tahsisi: Ütü ve buzdolabını aynı koliye koymak gibi, program çalışmadan önce bellekte ihtiyaç duyulacak alanlar belirlenir ve sabitlenir. Yani her veri için sabit boyutlarda alan ayrılır. Bu durum, bellek kullanımında esneklik sağlamaz ve verimsiz olabilir, tıpkı büyük bir koliyi küçük bir ürünü kargolamak için kullanmak gibi.
- Dinamik Bellek Tahsisi: Dinamik tahsis ile ütü için küçük bir koli, buzdolabı için büyük bir koli gibi, verilerimiz için yalnızca gereken kadar bellek ayrılır. Böylece program çalışırken ihtiyaç duyulan veri miktarına göre bellek daha verimli kullanılır. Yani bu şekilde uygulamanın bellek kullanımını optimize etmiş oluruz.
2. C#’ta Dinamik Bellek Tahsisi Nasıl Yapılır?
C# dilinde dinamik bellek tahsisini en yaygın olarak kullandığımız yapı List<T> sınıfıdır. Bu sınıf sayesinde dizilerin aksine, eleman sayısını program çalışırken dinamik olarak ayarlayabiliriz. İşte List<T> sınıfının kullanımı ile dinamik bellek tahsisini basit bir örnekle açıklayalım:
C++:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Yeni bir dinamik liste oluşturuyoruz
List<int> sayilar = new List<int>();
// Listeye eleman ekliyoruz
sayilar.Add(10);
sayilar.Add(20);
sayilar.Add(30);
// Eleman sayısı arttıkça bellekte yer ayrılıyor. Ütü eklendikçe kolinin büyüklüğü artıyor.
Console.WriteLine("Listedeki eleman sayısı: " + sayilar.Count);
// Tüm elemanları ekrana yazdıralım
foreach (int sayi in sayilar)
{
Console.WriteLine(sayi);
}
}
}
3. List<T> ile Bellek Yönetimi
Yukarıdaki kodda List<int> türünde bir liste oluşturduk ve içine eleman ekledik. List<T> sınıfınınAdd metodu sayesinde, listeye dilediğimiz kadar eleman ekleyebiliyoruz. Bu eklemeler sonucunda bellek ihtiyacımız arttıkça, C# bu bellek ihtiyacını otomatik olarak yönetir ve bize bu konuda yardımcı olur.4. Garbage Collector Nedir?
Dinamik bellek tahsisi yaparken, her eklediğimiz veri için bellekte yer ayrılır. Garbage Collector kullanılmayan belleği temizleyerek bellek sızıntılarını önlememize yardımcı olur. Programın çalışması sırasında kullanılmayan dinamik bellek alanlarını algılar ve bunları serbest bırakır. Kısacası otomatik yapıyor bellek temizliğini.C#’ta Garbage Collector sayesinde belleği manuel olarak serbest bırakmak zorunda kalmayız. Bunu siz eklemek zorunda değilsiniz uygulama kendi kendine yapmakta.
5. Ne Zaman Dinamik Bellek Tahsisini Tercih Etmeliyiz?
Dinamik bellek tahsisini aşağıdaki durumlarda tercih etmek idealdir:- Programda bellek gereksiniminin başlangıçta bilinmediği durumlarda
- Bir veri yapısının boyutunu, programın çalışması sırasında dinamik olarak değiştirmek gerektiğinde
- Listeye sürekli yeni veriler eklenecekse veya veri miktarı sürekli değişkenlik gösteriyorsa
1. new: Dinamik bellek tahsisi yaparken kullanılır. `new` anahtar kelimesiyle bellekte bir nesne veya dizi için alan ayırırız.
Kod:
int[] dizi = new int[5];
2. List<T>: Dinamik diziler oluşturmak için kullanılan generic bir koleksiyon sınıfıdır. `List<T>` sınıfı, eleman sayısına göre bellekte dinamik olarak genişleyebilir veya daralabilir. Kısacası lastik gibidir
Kod:
List<int> sayilar = new List<int>();
3. ArrayList: Generic olmayan dinamik koleksiyon sınıfıdır. Farklı türde veriler eklemeye imkan tanır, ancak generic olmadığı için `List<T>` kadar performanslı değildir.
Kod:
ArrayList liste = new ArrayList();
4. Dictionary<TKey, TValue>: Anahtar-değer (key-value) çiftleri şeklinde verileri saklayan bir koleksiyon sınıfıdır. Bu yapılar da dinamik olarak bellekte genişleyebilir. Mesela şehirleri plakalarla eşleştiren bir kod yazıyoruz, buradaki sınıf aşağıdaki şekilde tanımlanmalı.
Kod:
Dictionary<int, string> sehirler = new Dictionary<int, string>();
5. Stack ve Queue: LIFO (Last In, First Out) ve FIFO (First In, First Out) prensiplerine göre çalışan dinamik koleksiyon yapılarıdır. İhtiyaca göre bellekten dinamik olarak yer ayırabilirler.
Kod:
Stack<int> yigin = new Stack<int>();
Queue<int> kuyruk = new Queue<int>();
6. LinkedList<T>: Dinamik bellek kullanımını gösteren veri yapılarından biridir. Bağlı liste yapısı olduğundan bellekte dinamik olarak veri ekleyip çıkarma işlemlerinde avantaj sağlar.
Kod:
LinkedList<string> isimler = new LinkedList<string>();
7. HashSet<T>: Benzersiz elemanlardan oluşan dinamik bir koleksiyon yapısıdır. Bu yapı da dinamik olarak bellekten alan ayırabilir.
Kod:
HashSet<int> benzersizSayilar = new HashSet<int>();
Konu bu kadar, kolay gelsin.





