Kurs
Bellek yönetimi, programlamanın önemli ancak çoğu zaman göz ardı edilen bir yönüdür. Doğru ele alınmadığında yavaş uygulamalara, beklenmedik çöküşlere veya hatta bellek sızıntılarına yol açabilir. Neyse ki Python, bellek yönetimini otomatik olarak yapan yerleşik bir sistem olan çöp toplama süreci sayesinde bununla ilgilenir.
Peki Python’ın çöp toplaması nasıl çalışır ve neden umursamalısınız? Bu süreci anlamak, projelerinizin karmaşıklığı arttıkça bile iyi performans gösteren, verimli ve hatasız kod yazmanın anahtarıdır.
Bu makalenin sonunda, Python’da çöp toplamanın temellerini ve neden önemli olduğunu bilecek, Python’ın belleği yönetmek için başvuru sayımı ve nesilsel çöp toplamayı nasıl kullandığını anlayacak ve bellek sızıntılarından kaçınmak için bazı ipuçları öğreneceksiniz. Ayrıca sonunda, ortamınızdaki kaynakları nasıl tahsis edeceğinizi ve ek yükü nasıl değerlendireceğinizi öğreten, çöp toplamanın yalnızca bir parçası olduğu daha geniş konuları kapsayan Verimli Python Kodu Yazma kursumuza kaydolmanızı öneririm.
Python’da Çöp Toplama Nedir?
Çöp toplama, Python’ın belleği otomatik olarak yönetme biçimidir; artık kullanılmayan belleği boşaltarak uygulamanızın sorunsuz çalışmasını sağlar. Basitçe söylemek gerekirse, işini bitiren nesneleri ortadan kaldıran, kodunuzun ardından temizlik yapan görünmez bir görevli gibidir.

“Python çöpleri topluyor.” Görsel: Dall-E 2
Python’da neden çöp toplamaya ihtiyaç duyarız?
Her uygulamada, verileri depolamak, hesaplamalar yapmak veya görevleri yönetmek için nesneler oluşturulur. Ancak bu nesneler işini bitirdikten sonra, açıkça kaldırılana kadar bellek alanını işgal etmeye devam eder. Bu kullanılmayan nesneler birikirse, uygulamanızın gereğinden fazla bellek kullanmasına neden olabilir; bu da performansın düşmesine ve olası çöküşlere yol açar.
Çöp toplama bu tür senaryoları önler. Bir nesnenin artık gerekli olmadığını (kodunuzun hiçbir bölümünün ona başvurmadığını) otomatik olarak algılar ve ardından onu bellekten güvenli bir şekilde kaldırır. Bu süreç şunlara yardımcı olur:
- Bellek Sızıntılarını Önleme: Kullanılmayan nesneleri otomatik olarak temizleyerek, artık gerekmeyen belleğin serbest bırakılmaması durumunda ortaya çıkan bellek sızıntısı riskini azaltır.
- Performansı Optimize Etme: Belleği boşaltarak, özellikle uzun süre çalışan programlarda veya büyük miktarda veriyi işleyen uygulamalarda performansın korunmasına yardımcı olur.
- Geliştirmeyi Basitleştirme: Python bellek yönetimini otomatik olarak üstlendiği için geliştiriciler bellek yönetimiyle uğraşmak yerine kod yazmaya odaklanabilir.
Python Çöp Toplamayı Otomatik Olarak Nasıl Uygular
Python’ın çöp toplaması, geliştiricilerin bellek yönetimi yerine kod yazmaya odaklanmasına olanak tanıyacak şekilde belleği otomatik olarak yönetmek için tasarlanmış karmaşık bir sistemdir. Python, çöp toplamayı uygulamak için başlıca iki mekanizma kullanır: başvuru sayımı ve nesilsel çöp toplama. Bu mekanizmalar birlikte çalışarak belleğin verimli bir şekilde yönetilmesini sağlar, bellek sızıntısı olasılığını en aza indirir ve uygulamanızın performansını optimize eder.
Bu mekanizmalara bakmadan önce, çöp toplama sürecinin en çok kullanılan Python uygulaması olan CPython için en geçerli olduğunu belirtmek önemlidir. PyPy veya Jython gibi diğer uygulamalar çöp toplamayı farklı şekilde ele alabilse de, CPython uygulamalarınızın sorunsuz çalışması için büyük ölçüde bu iki yönteme dayanır.
Başvuru sayımı
Başvuru sayımı, Python’ın belleği yönetmek için kullandığı temel yöntemdir. Özünde başvuru sayımı, bellekteki bir nesneye yapılan başvuruların (veya işaretçilerin) sayısının takip edilmesini içerir. Bir nesneye her yeni başvuru oluşturulduğunda Python o nesnenin başvuru sayısını artırır. Tersine, bir başvuru kaldırıldığında veya kapsam dışına çıktığında Python başvuru sayısını azaltır. İşleyişi şöyledir:
- Başvuruların Takibi: Python’daki her nesnenin bir başvuru sayısı vardır ve nesneye başvurulduğunda veya başvuru kaldırıldığında güncellenir. Örneğin, bir nesneyi bir değişkene atamak veya bir fonksiyona geçirmek başvuru sayısını artırırken, değişkeni silmek sayıyı azaltır.
- Belleğin Tahsisini Geri Alma: Bir nesnenin başvuru sayısı sıfıra düştüğünde, yani kodunuzun hiçbir bölümü o nesneyi kullanmadığında, Python o nesnenin kapladığı belleği otomatik olarak serbest bırakır.
Verimli olmasına rağmen başvuru sayımının sınırlamaları vardır. En önemlisi, iki veya daha fazla nesnenin birbirine başvurmasıyla bir döngü oluşturduğu döngüsel başvuruları ele alamamasıdır. Bu durumlarda, başvuru sayıları asla sıfıra ulaşmaz ve belleğin geri kazanılmasını engeller. İşte bu noktada nesilsel çöp toplama devreye girer.
Nesilsel çöp toplama
Başvuru sayımının sınırlamalarını aşmak için Python nesilsel çöp toplamayı da kullanır. Bu gelişmiş yöntem, döngüsel başvuruları ele almak ve bellek yönetimi verimliliğini artırmak için tasarlanmıştır. Nesilsel çöp toplamanın ardındaki temel fikir, nesnelerin çoğunun kısa ömürlü (geçici) veya uzun ömürlü (kalıcı) olduğuna dair gözleme dayanır. Nesneleri yaşlarına göre kategorize ederek Python çöp toplama sürecini optimize eder. Nesilsel çöp toplamanın işleyişi şöyledir:
-
Nesiller: Python’ın çöp toplayıcısı nesneleri üç nesile ayırır: Nesil 0 (en genç), Nesil 1 (orta yaşlı) ve Nesil 2 (en yaşlı). Yeni nesneler Nesil 0’a yerleştirilir ve çöp toplamadan sağ çıkarlarsa bir sonraki nesile taşınırlar.
-
Genç Nesnelere Öncelik Verme: Çöp toplayıcı, genç nesneler (Nesil 0) üzerinde daha sık çalışır; çünkü bu nesnelerin hızla kullanılmaz hale gelme olasılığı daha yüksektir. Nesneler yaşlandıkça ve üst nesillere taşındıkça daha seyrek toplanırlar. Bu yaklaşım, yakında atılma olasılığı yüksek olan nesnelere daha fazla odaklanarak çöp toplama ek yükünü azaltır.
-
Döngüsel Başvuruları Ele Alma: Nesilsel çöp toplama, döngüsel başvurulara dahil olan nesneleri belirleme ve toplamada özellikle etkilidir. Toplama sürecinde Python’ın çöp toplayıcısı bu döngüleri tespit edip belleği geri kazanabilir ve döngüsel başvuruların neden olduğu bellek sızıntılarını engeller.
Python Çöp Toplamayı Elle Nasıl Tetikleyebilirsiniz
Python’ın çöp toplama sistemi bellek yönetimini otomatik olarak halletmek üzere tasarlanmıştır; ancak çöp toplamayı elle yönetmenin faydalı olabileceği durumlar vardır. Bir göz atalım.
Python’da çöp toplamayı başlatma
Çoğu durumda Python’ın çöp toplayıcısı otomatik olarak çalışır ve müdahale gerektirmeden kullanılmayan nesneleri temizler. Ancak belleği boşaltmak için çöp toplamayı elle tetiklemek isteyebileceğiniz durumlar olabilir. Bu, bellek kullanımının daha yakından yönetilmesi gereken uzun süre çalışan uygulamalarda veya bellek yoğun süreçlerde özellikle yararlıdır.
Python’da çöp toplamayı elle tetiklemek için gc.collect() fonksiyonunu kullanabilirsiniz. Bu fonksiyon, çöp toplayıcının hemen çalışmasını zorlar ve artık kullanılmayan belleği geri kazanır. İşleyişi şöyledir:
import gc
# Trigger garbage collection manually
gc.collect()
gc.collect() çağrıldığında Python’ın çöp toplayıcısı tam bir toplama gerçekleştirir; bellekteki tüm nesneleri inceler ve artık başvurulmayanları serbest bırakır. Bu, özellikle şu senaryolarda faydalıdır:
- Bellek Yoğun Uygulamalar: Büyük miktarda veri işleyen veya çok sayıda nesne oluşturan uygulamalarda, çöp toplamayı elle tetiklemek kritik anlarda belleği boşaltmaya yardımcı olarak şişmeyi azaltabilir.
- Uzun Süre Çalışan Süreçler: Sunucular veya arka plan görevleri gibi uzun süre çalışan hizmetlerde, çöp toplamayı elle yönetmek istikrarlı bir bellek kullanımını sürdürmeye yardımcı olur ve uygulamanın zaman içinde duyarlı ve verimli kalmasını sağlar.
Ancak gc.collect() çağrısını ölçülü kullanmak önemlidir. Sık sık elle çöp toplamak gereksiz ek yüke yol açabilir; çünkü süreç kaynak yoğun olabilir. Genellikle olası bellek sorunlarını tespit ettiğiniz veya tam olarak belirli bir anda belleği boşaltmanız gerektiği senaryolarda en iyi sonucu verir.
Çöp toplamayı devre dışı bırakma
Bazı durumlarda Python’ın otomatik çöp toplamayı geçici olarak devre dışı bırakmanın faydalı olduğunu düşünebilirsiniz. Bu, gerçek zamanlı uygulamalarda, performans açısından kritik kod bölümlerinde veya kesintileri en aza indirmek istediğiniz işlemler sırasında çöp toplamanın getirdiği ek yükün performansı olumsuz etkileyebileceği senaryolarda yararlı olabilir.
Çöp toplayıcıyı devre dışı bırakmak için gc.disable() fonksiyonunu kullanabilirsiniz:
import gc
# Disable automatic garbage collection
gc.disable()
Çöp toplama devre dışı bırakıldığında, Python kullanılmayan nesneleri otomatik olarak toplamayı ve bellekten çıkarmayı durdurur. Bu, belirli durumlarda daha öngörülebilir performans sağlayabilir; çünkü çöp toplayıcının kritik işlemler sırasında beklenmedik şekilde çalışmasını engeller.
Ancak çöp toplamayı devre dışı bırakmanın riskleri vardır:
- Bellek Sızıntıları: Çöp toplama olmadan, kullanılmayan nesneler süreç bitene kadar bellekte kalır; bu da bellek sızıntılarına yol açabilir. Bu, bellek kullanımının kontrolsüz biçimde artabileceği uzun süre çalışan uygulamalarda özellikle sorunludur.
- Döngüsel Başvurular: Çöp toplama olmadan döngüsel başvurular otomatik olarak çözülmediği için, çöp toplayıcıyı devre dışı bırakmak kodunuzda döngüler varsa bellek sorunlarını daha da kötüleştirebilir.
Bu nedenlerle, kodunuzun performans açısından kritik bölümünü çalıştırdıktan sonra çöp toplamayı yeniden etkinleştirmek şarttır. Çöp toplayıcıyı gc.enable() ile yeniden etkinleştirebilirsiniz:
# Re-enable automatic garbage collection
gc.enable()
Elle çöp toplama için bazı en iyi uygulamalara bakalım:
- Ölçülü Kullanın: Elle çöp toplama yalnızca gerektiğinde uygulanmalıdır. Aşırı kullanım performans düşüşüne yol açabilir.
- Profilleme ile Birleştirin: Çöp toplamayı elle tetiklemeden veya devre dışı bırakmadan önce, uygulamanızı profilleyerek bellek kullanım kalıplarını anlamayı düşünün. Bu, elle müdahalenin gerekip gerekmediğini ve en çok nerede etki edeceğini belirlemenize yardımcı olabilir.
- Gerektiğinde Yeniden Etkinleştirin: Çöp toplamayı devre dışı bırakırsanız, kritik kod bölümü biter bitmez yeniden etkinleştirmeyi unutmayın. Bu, uzun vadede belleğin verimli şekilde yönetilmesini sağlar.
Elle çöp toplamayı nasıl ve ne zaman kullanacağınızı anlayarak, uygulamanızın bellek yönetimi üzerinde daha ince ayar kontrolü elde edebilirsiniz. Bu yalnızca performansı optimize etmekle kalmaz, aynı zamanda uygulamanızın kararlılığını etkileyebilecek bellekle ilgili sorunları da önler.
Bir sonraki bölümde, Python’da yaygın çöp toplama sorunlarını inceleyecek ve bunları hata ayıklamak ve çözmek için pratik ipuçları sunacağız.
Python Geliştiricileri İçin Pratik Hususlar
Belleği verimli yönetmek, yüksek performanslı Python uygulamaları yazmak için kritiktir. Python’ın çöp toplama sistemi bellek yönetimi görevlerinin çoğunu otomatik olarak halletse de, geliştiricilerin yaygın tuzaklardan kaçınmak ve bellek kullanımını optimize etmek için atabileceği pratik adımlar vardır. Bu bölümde, bellek sızıntılarından kaçınma, döngüsel başvurularla başa çıkma ve Python uygulamalarında çok sayıda nesneyi yönetme stratejilerini ele alacağız.
Bellek sızıntılarından kaçınma
Bellek sızıntıları, artık gerekmeyen nesnelerin düzgün şekilde serbest bırakılmamasıyla ortaya çıkar ve uygulamanın zaman içinde daha fazla bellek tüketmesine neden olur. Bu, performansın düşmesine ve hatta uygulamanın çökmesine yol açabilir. Bellekteki nesneleri izlemek için Python’ın gc modülünü kullanabilirsiniz. Bellekteki nesnelerin sayısına bakarak beklenmedik artışları görebilir ve bu da bir bellek sızıntısına işaret edebilir:
import gc
# Get a list of all objects tracked by the garbage collector
all_objects = gc.get_objects()
print(f"Number of tracked objects: {len(all_objects)}")
Bir nesnenin çöp toplanmadığından şüpheleniyorsanız, gc.get_referrers() fonksiyonu o nesneyi bellekte tutanların ne olduğunu belirlemeye yardımcı olur. Bu fonksiyon, verilen nesneye başvuran nesnelerin bir listesini döndürür; böylece bu başvuruların gerekli olup olmadığını veya kaldırılıp kaldırılamayacağını belirleyebilirsiniz:
some_object = ...
referrers = gc.get_referrers(some_object)
print(f"Object is being referenced by: {referrers}")
Bellek sızıntılarından kaçınmanın bir diğer yolu da özellikle önbellekleme senaryolarında zayıf başvurular kullanmaktır. weakref modülü, nesnenin başvuru sayısını artırmayan başvurular oluşturmanıza olanak tanır:
import weakref
class MyClass:
pass
obj = MyClass()
weak_obj = weakref.ref(obj)
print(weak_obj()) # Access the object
del obj # Delete the strong reference
print(weak_obj()) # None, as the object is now collected
Döngüsel başvurularla başa çıkma
Döngüsel başvurular, iki veya daha fazla nesnenin birbirine başvurmasıyla başvuru sayılarının asla sıfıra ulaşmamasına neden olan döngüler ortaya çıktığında oluşur. Çöp toplayıcı bu nesneleri tespit edip toplayamazsa bellek sızıntılarına yol açabilir.
Python’ın nesilsel çöp toplayıcısı döngüsel başvuruları ele almak üzere tasarlanmıştır; ancak yine de gereksiz döngüler oluşturmamak en iyisidir. gc modülünü kullanarak bir toplama tetikleyip, toplanamayan döngüdeki nesneleri içeren gc.garbage listesini kontrol ederek döngüsel başvuruların parçası olan nesneleri tespit edebilirsiniz:
import gc
# Trigger garbage collection and get the number of uncollectable objects
gc.collect()
uncollectable_objects = gc.garbage
print(f"Number of uncollectable objects: {len(uncollectable_objects)}")
Döngüsel başvuruları önlemek için, artık gerekmediğinde başvuruları açıkça kaldırarak döngüyü kırmayı düşünün. Bunu başvuruyu None olarak ayarlayarak veya güçlü başvuru döngülerinden özellikle kaçınan zayıf başvurular kullanarak yapabilirsiniz. Ayrıca, veri yapılarınızın ve nesne ilişkilerinizin tasarımını basitleştirmek, döngü oluşturma olasılığını azaltabilir.
Çok sayıda nesneyi yönetme
Kısa sürede çok sayıda nesne oluşturup yok etmek, Python’ın çöp toplayıcısını zorlayabilir. Büyük veri kümeleriyle çalışan, gerçek zamanlı veri işleyen veya karmaşık durumlar gerçekleştiren uygulamaları düşünün.
Bir fikir, nesne oluşturma ve silme işlemlerini toplu yapmaktır. Nesneleri teker teker oluşturup yok etmek yerine, bu işlemleri toplu yapmak çöp toplama sıklığını azaltabilir ve çöp toplayıcının daha verimli çalışmasına olanak tanır. Örneğin:
objects = []
for i in range(1000):
obj = SomeClass()
objects.append(obj)
# Process all objects at once, then delete them
del objects[:]
gc.collect() # Optionally trigger a manual garbage collection
Bir diğer husus, nesnelerin ömürlerini optimize ederek onların ya kısa ömürlü ya da uzun ömürlü olmasını sağlamaktır. Kısa ömürlü nesneler hızlıca toplanır; uzun ömürlü nesneler ise daha seyrek toplanan üst nesillere taşınır.
Nesnelerin sıklıkla oluşturulup yok edildiği senaryolarda, nesne havuzu faydalı bir tekniktir. Nesne havuzu, sabit sayıda nesneyi yeniden kullanır; böylece çöp toplayıcı üzerindeki yükü azaltır ve bellek kısıtlı ortamlarda performansı artırır. İşte bir nesne havuzu uygulaması örneği:
class ObjectPool:
def __init__(self, size):
self.pool = [SomeClass() for _ in range(size)]
def get(self):
return self.pool.pop()
def release(self, obj):
self.pool.append(obj)
Nesne havuzları özellikle performansın kritik olduğu gerçek zamanlı uygulamalarda veya oyunlarda faydalıdır; çünkü sık nesne oluşturma ve yok etme işlemlerinin ek yükü önemli olabilir.
Sonuç
Bu makalede, Python’ın çöp toplama sistemini; belleği otomatik olarak nasıl yönettiğinden, performansı iyileştirmek için alabileceğiniz elle müdahalelere kadar ele aldık. Başvuru sayımı ile nesilsel çöp toplamanın birleşimi Python’ın belleği etkili biçimde yönetmesini sağlar; ancak bazen elle müdahale de faydalıdır. Bu rehberde belirtilen en iyi uygulamaları izleyerek bellek sızıntılarından kaçınabilir, performansı artırabilir ve uygulamalarınızın belleği nasıl yönettiği üzerinde daha fazla kontrol sahibi olabilirsiniz.
Bellek yönetimi ve genel kod optimizasyonunda daha ileri konuları keşfetmek istiyorsanız, birçok harika DataCamp kaynağı mevcuttur. Performans darboğazlarını tespit etmek için yararlı olan Python’da Bellek Verimli Sınıflar Nasıl Yazılır ve Python’da Bellek Profilleme eğitimlerimizi okuyabilirsiniz. Ayrıca, daha verimli Python kodu yazmayı öğrenmek her kariyer için her zaman faydalıdır.
Veri alanında deneyimli bir profesyonel ve yazar; veri dünyasında uzmanlaşmak isteyenleri güçlendirmeye tutkuyla bağlı.
Python Çöp Toplama Hakkında SSS
Python uygulamalarında bellek kullanımını nasıl izleyebilirim?
memory_profiler, tracemalloc ve objgraph gibi araçları kullanarak. Bu araçlar bellek tüketimini izlemeye, bellek sızıntılarını belirlemeye ve bellek kullanımını optimize etmeye yardımcı olur.
Python’da çöp toplamayı elle nasıl tetikleyebilirim?
Bunu gc modülünü kullanarak yapabilirsiniz. gc.collect() gibi fonksiyonlar, belirli senaryolarda hata ayıklama veya bellek kullanımını optimize etmek için yararlı olabilen bir çöp toplama döngüsünü zorla başlatmanıza olanak tanır.
Python’ın çöp toplaması devre dışı bırakılabilir mi?
Evet, gc modülünü kullanarak Python’ın çöp toplamayı devre dışı bırakabilirsiniz. gc.disable() çağrısı yaparak çöp toplayıcının çalışmasını engelleyebilirsiniz.

