Python’da Bellek Nasıl Yönetiliyor? Namespace ve GC Nedir?



Çok şanslısınız. Bundan 30 sene önceye gitseydiniz, yazılım geliştirirken sizi çok uğraştıracak sorunlardan biri bellek yönetimi olacaktı. Bellek yönetimiyle ilgili sorunlardan bazıları şöyleydi:

  • Yazılımın üretebileceği olası veri miktarını hesaplayıp bellekte veriler için yer ayırmanız (adresler) gerekecekti.
  • Bu yerleri (adresler) en etkili şekilde kullanmanız gerekecekti. Eğer az veri üretilirse, bazı adresleri boşa ayıracaktınız. Çok üretilmesi gibi bir seçenek de yok (çünkü yeriniz yok).
  • Ve bellek yönetimi hedeflediğiniz işlemci mimarisine paralel olarak yapılacaktı. Eski bir oyun konsolunun eski bir kişisel bilgisayara göre belleğinin oldukça düşük olduğunu düşünün.

Bugün ise bu sorunların pek çoğuyla uğraşmıyoruz. Tabi hala elle bellek yönetiminin olduğu diller de mevcut, ama pek çok dil garbage collection (en kaba tabiriyle, çöp toplama) yöntemini kullanmakta.

GC yönteminde dilin derleyicisi veya yorumlayıcısı, periyodik olarak belleği tarar ve (dilin mimarisine bağlı olarak) herhangi bir değişkenin/adın mantıksal olarak artık erişilemeyeceğine karar veriyorsa ona olan erişimi kaldırır ve/veya bellekten kaldırır. Bu, dilin mimari yapısına da bağlıdır. Bir dilin GC sisteminde edindiğiniz alışkanlığı diğer bir dile geçtiğinizde uygulayamayabiliriz.

Ad ve Adalanı (ya da adalanı) Nedir?

Biz buna ilk önce ad (name) ile başlayalım. Ad, değişken olarak özetlenebilir, ama değişkenden farklı olarak bulundukları bir sınır vardır. Siz bir ada erişmek istediğinizde Python önce yerel adları (local names) kontrol eder, eğer bulamazsa genel adları (global names) kontrol eder.

Bunu bir örnekle taçlandırmak lazım. Aşağıdaki kodu inceleyelim:

Gördüğünüz üzere, i adını ilk çağırdığımızda 2 değerini bize veriyor. Daha sonra myfunc fonksiyonumuzu çağırıyoruz, o da içerisinde bir i adına 4 değerini verip onu gösteriyor. Ne olmasını umuyoruz? myfunc içerisinde i adını yeniden tanımladığımıza göre ikinci kez (son satırda)  i adını çağırdığımızda bize 4 vermiyor. Yani, myfunc içerisindeki i adı, sadece orada olan bir ad. Birinci satırdakini etkilemiyor.

Peki, ben myfunc içerisinde hiç i tanımlamasaydım, ne olacaktı? Yani, aşağıdaki gibi bir kod.

O zaman myfunc, içerisinde i adını bulamadığı için dışarı bakacaktı, ki o da ilk satırda. Yani Python, bir adı ararken ilk önce yerel adalanına bakar (bu durumda fonksiyonun içi), eğer bulamazsa genel adalanına başvurur.

Peki adalanında

Peki Python’da GC Nasıl Çalışır?

Öncelikle Python’un namespace sistemine (bizim sözlüğümüzde isim uzayı olarak geçse de adalanı diye bahsedeceğim) önem verilir. Tim Peters’ın da Zen of Python‘da belirttiği gibi:

Namespaces are one honking great idea — let’s do more of those!

Adalanları gerçekten mükemmel bir fikir, bunu kullanalım.







Namespace sisteminde her verinin referans gösterildiği bir ad vardır (biz buna değişken de diyoruz). Örnek olarak;

Bu kod parçasında 2, bellekte duran bir veri. a ise bir ad. a2 verisine referans veriyor. Yani siz a adını ne zaman kullanırsanız/çağırırsanız, bellekteki 2 verisi bize geliyor. Peki, başka bir şey yapalım:

Burada a ve b adları 2 verisini işaret ediyor. Peki, soru şu: Sizce, Python bellekte iki ayrı 2 verisi mi oluşturuyor?

Python’da bir değişkenin bellekteki adresini alabilmek için id fonksiyonunu kullanıyoruz:

Burada da gördüğünüz üzere, iki ad da aynı adrese sahip. Yani, aynı şeye işaret ediyorlar. Böylece, fazla veri yaratmayarak, aynı şeye işaret ederek, bellekte ek veri barındırmaktansa veri tasarrufu sağlıyoruz.

a ve b aynı veriye gönderimde bulunuyorlar, dolayısıyla a ve b aynı şey.

Burada ve ilerde aynı adrese gönderimde bulunan adlara aynı şey diyorum.

Yeri gelmişken, iki adın da aynı adrese gönderimde bulunduğunu kullanmak için aşağıdaki yöntemleri de kullanabilirsiniz:

Şöyle bir şey yapalım bir de:

Böylece a adının gönderimde bulunduğu adres değişmiş oldu. Görselleştirirsek;

a ve b farklı verilere gönderimde bulunuyorlar, dolayısıyla a ve b farklı şeyler.

Yani Python otomatik bir şekilde hangi adın hangi adrese gönderimde bulunduğunu ayarlıyor. Peki, adrese gönderimde bulunan ad, namespace‘ten silindiği zaman ne oluyor? Tabi ki de siliniyor.

Peki ya iki ayrı ad (ya da değişken) bir adrese gönderimde bulunuyorsa? Hem ad, hem adresteki veri mi silinecek? Tabi ki hayır. Sadece ad silinir. Yani kısaca, “a” ile 2 verisine ulaşamazsınız. Ama aynı adresteki 2 verisi hala bellektedir, çünkü zaten başka bir ad ona erişebilmektedir.

a ve b, aynı adrese gönderimde bulunan iki ayrı adlar. a silindiği zaman, sadece gönderim silinir.

 



Beğendin mi? Arkadaşlarınla ​​paylaş!

110
, 110 puan
Emoji olarak yorumla :)
eh işte! eh işte!
0
eh işte!
Harika Harika
0
Harika
Hahaha! Hahaha!
0
Hahaha!
Vay be! Vay be!
0
Vay be!
Şekilsin Şekilsin
0
Şekilsin
Muhteşem Muhteşem
0
Muhteşem
Beğendim Beğendim
0
Beğendim
Beğenmedim Beğenmedim
0
Beğenmedim

Python’da Bellek Nasıl Yönetiliyor? Namespace ve GC Nedir?

Giriş Yap

Hoşgeldin, sefa getirdin :)

Şifre Sıfırla

Şifreni bidaha unutma lütfen :)

Geri git :
Giriş Yap