folder Tahribat.com Forumları
linefolder Python
linefolder Python Hafıza Yönetimi Ve Garbage Collection Hakkında



Python Hafıza Yönetimi Ve Garbage Collection Hakkında

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    nick6
    0x656e
    0x656e's avatar
    Kayıt Tarihi: 19/Mayıs/2012
    Homo

    Python Hafıza Yönetimi ve Garbage Collection Hakkında

    Python Garbage Collector

    Garbage Collector Neymiş?

    Garbage collector Türkçe'ye çevrildiğinde çöp toplayıcı anlamına gelmektedir. Aslında yazılım dillerinde ki temel mantığıda aynıdır. Nedir bu olay derseniz de basit anlamda kodunuz üzerinde kullandığınız her nesne/obje memory'de bir alan kaplar. Bu alan verinizin boyutuna göredir. Örnek vermek gerekirse C'de 32bit bir integer değişkeni tanımlamışsanız bu değişken için memory üzerinde 31 bitlik bir alan açılır ve bu alan içerisinde siz değerlerinizi tutabilirsiniz. Geri kalan bir 1 bit ise işaret biti olarak kullanılır.

    Buraya kadar her şey tamam. Peki o zaman şöyle yapalım biz programın açılışında bir değişken tanımladık ve bunu 1 kere kullandık ve yazdığımız dil otomatik hafıza yönetim'i olmayan bir dil(Örn: C) ne olacak peki? Bu ayırdığımız alan program sonlanana kadar hafızada gereksiz yer kaplayacak.

    İşte bu sebepten dolayı günümüzde kullanılan çoğu scripting dili ile birlikte Go, Java, C# otomatik hafıza yönetimine sahiptir. Bununla birlikte isterseniz C ve C++'a da Boehm-Demers-Weiser ile ekleyebilirsiniz.

    Peki bu işlem nasıl yapılıyor? Burada 2 farklı yöntem karşımıza çıkıyor. 1. Reference Counting 2. Tracing

    Bu kısımları kısaca bahsedip geçeceğim.

    Reference Counting Nedir?

    Bu metotda bizim kodumuzu yazarken hafızada kullanacağımız tüm nesne/objelerin reference tablosu tutuluyor. Basit anlamda kafanızda canlanması için örnek veriyorum A şeklinde bir değişkenimiz var ve biz bunu toplama(A) fonksiyonunda kullanıyoruz. Burada toplama fonksiyonunda A'yı referans aldığımızdan dolayı bu tabloda A'nın reference count'u 1 olacaktır. Tamam şimdi fonksiyondan çıktık artık A'nın bir işlevi kalmadı ve toplama fonksiyonunu bir yere atamadık. Bu sebeple tabloda değişkenimizin reference count'ı 0 oldu ve artık hafızadan kapladığı alan boşaltıldı. Python dilinde de Reference Counting ve Döngü tespiti kullanılır.

    Reference counting'in bazı dezavantajları var: 1. Thread-Safe bir yapıda değil. Eğer multithread yapıda bir uygulama yazmışsanız bu sorunlara yol açıyor. Basit anlamda yine örneklendirmeye gideceğim. 1 thread'iniz bir refcount'u artırırken bir thread'iniz bu refcount'u 1 azaltabilir. 2. Her obje için bir referans count değeri oluşturuyor. Bu da memoryde fazladan alan demek. 3. Cyclical Reference'ları tanımlayamıyor. Örnek:

    import sys
    print(sys.getrefcount(5))
    a = 5
    b = a
    print(sys.getrefcount(5))
    del a
    print(sys.getrefcount(5))
    Output:
    69
    71
    70
    

    Tracing Garbage Collector

    En fazla kullanılan yöntemdir. Bu Garbage collectorümüz ise biraz karışık. Yine de elimden geldiğince basit bir şekilde anlatmaya çalışacağım. Yazılımımız çalıştığında Memory de Root Set'imiz oluşturuyor bu bizim Memoryde ki en üst alanımız bundan sonra ki tüm obje ve nesneler child olarak memory içerisinde yer ediniyor. Tracing kısmı işte burada devreye giriyor. 2 fazlı bir çalışması bulunuyor. 1. Root Set'imizin erişebildiği tüm objeler/nesneler kontrol ediliyor ve root setimizden bu objelere/nesnelere erişiliyorsa bu obje/nesne Alive olarak işaretleniyor.(Mark bit) 2. Bu faz ise Sweep olarak geçmekte. Bu kısımda algoritmamız yine tüm memory'i geziyor eğer Alive işaretlenmiş bir memory alanı varsa bu alan üzerinde Mark biti gelecekte ki Garbage Collection döngüsü için kaldırıyor ve sonra ki memory adresine geçiyor. Eğer bu adres daha önce ziyaret edilmemiş yani Mark bit verilmemişse bunu Free Memory kısmına ekliyor.

    Tabi bu kadarla kalmıyor işin ilerleyen kısımlarında Mark-Compact gibi aşamaları da mevcut ama basit anlamda bu şekilde.

    Wiki üzerinden Tracing'i anlatan görsel: Tracing Çöp Toplayıcı

    Python'da İşler Nasıl Gidiyor?

    Yukarıdaki başlıklarda genel olarak Garbage Collection'ın ne olduğundan vs bahsettik sıra Python'a gelince burada işler biraz karışıyor.

    Bu kısımda karşımıza generational garbage collection, gil gibi kavramlar karşımıza çıkıyor. Sırası ile gidelim.

    Python'da iki tür garbage collection kullanılıyor bunlardan 1 tanesi yukarıda da bahsedilen Reference Counting, diğeri ise bir Tracing tipi olan Generational Garbage Collection'dır.

    Generational Garbage Collection Nedir?

    Bu garbage collection tipinin mottosu "young objects are much more likely to die than old objects" yani kısaca genç olan erken ölür.

    Bu GC tipinde objeler jenerasyonlarına ayrılıyor, 3 adet grup bulunur. 1. Generation 0 - Short live 2. Generation 1 - Medium live 3. Generation 2 - Long live

    Bir obje GC sonrası yaşamına devam ediyorsa bir sonraki jenerasyona eklenir. Eğer yeni bir obje tanımlanmışsa bu obje Gen 0 da başlayacaktır. Yine gerçek hayattan bir örneklendirme yapayım. Yeni birisiyle tanıştınız. Beyninizde bu tanıştığınız kişi Gen0 grubuna Ahmet1 olarak yerleştirildi ve aynı anda 5 Ahmet ile tanıştınız. Sonra Kadıköy'de bir kafede biranızı yudumlarken Ahmet1 ile karşılaştınız ve oturup karşılıklı sohbet ettiniz. Ahmet1 artık Gen1 grubuna girdi ve Gen0 grubunda ki tüm Ahmetler hafızanızdan silindi. Eh Ahmet1 ile daha sonraları bir sür badire atlattınız(Bir sürü GC evresinden tertemiz çıktı) ve hayatınızda vazgeçilmez oldu.(Runtime'da ihtiyaç duyulan bir obje?!). Artık Ahmet1Gen2 grubunda oldu.

    Sanırım en kısa bu şekilde anlatabilirim :D

    GIL (Global Interpreter Lock)

    Bu arkadaşımız Python kodumuzun sadece tek bir thread tarafından çalıştırılmasını sağlıyor. Her kod yalnızca 1 thread üstünde çalışıyor. Yani arkaplanda çalışan her interpreter processde o process'e ait bir de GIL bulunuyor. O Process'e ait işlemleri başka bir thread çalıştıramıyor. Bunun sebebi ise yine üst kısımlarda bahsetmiş olduğumuz Reference Counting. Eş zamanlı olarak Reference Counting'in önüne geçebilmek için böyle bir yola gidilmiş.

    GIL'in bu özelliği sebebiyle GC süreçleri hızlanıyor fakat Python kodumuzun sadece tek bir Thread'de çalışması gerekiyor.

    Dipnot: GIL bir ara kaldırılmak istenmiş hatta Patch'de çıkmış fakat şöyle bir sorun ortaya çıkmış. Yazdığımız kodlar multithread bir yapıdaysa işlemler hızlanmış fakat eğer single thread bir uygulama yazmışsanız performans kaybı %50 gibi bir sayıya ulaşmış.

    Python'da Objeler

    Pythonda bir değişken atadığınızda ne oluyor biliyor musunuz? Bu atadığınız değişken memoryde hali hazırda yaratılmış bir Objeye refererans vererek kullanılıyor.

    Örnek vermek gerekirse siz a ve b adında iki farklı değişken tanımladınız bu değişkenlerin değeri de 500 diyelim. İşte bu değişkenler aslında Memory üzerinde hali hazırda obje olarak bulunan 500 objesini işaret ediyor.

    Pythonda objelerin memory üzerinde tutulması ise şu şekilde oluyor. ||PyObject | -| -| |type|integer| |refcount|2| |value|500|

    Kod olarak açıklarsak eğer:

    a = 500
    b = 500
    print(id(500))
    print(id(a),id(a)) 
    output:
    49670448
    49670448 49670448
    

    Gördüğünüz gibi iki farklı değişkenim, hatta bir integer'ım var ve aslında hepsi temelde memoryde ki 500 değerini barındıran PyObject'e referans veriyor. Bir de aşağıdaki koda bakalım.

    import sys
    print(sys.getrefcount(500))
    a = 500
    b = 500
    print(sys.getrefcount(500))
    print(id(500))
    print(id(a),id(a))
    
    print(sys.getrefcount(500))
    

    Çıktısı aşağıdaki gibi olacaktır.

    2
    4
    49671840
    49671840 49671840
    4
    

    ID'lerini bir kenara bırakırsak başlangıçta 500 değerini tutan Objemizin count'u 2 olarak gözükmekte biz bu değeri a ve b değişkenlerine verdiğimizde refcount 4 oluyor fakat print ile yazdırdığımız 500 değeri refcountu etkilemiyor. Bunun nedeni herhangi bir referans vermeden direkt yazdırmamızdan dolayıdır.

    Aslında yazıyı biraz daha uzatıp __slots__dan ve Python üzerindeki veri tipleri ve bu veri tiplerinin kapladıkları alan gibi konulardan bahsetmek istiyordum fakat bir baktım ki zaten sevgili Mazlum Ağar bu konudan bahsetmiş. İlgili yazının linkini hemen aşağıya iliştiriyorum.

    Python Tricks Slots

    Konu biraz dağınık olmuş olabilir bu sebeple kusura bakmayınız. Yazı tamamen benimde bilmediğim konu üzerine yaptığım araştırmalar neticesinde çıkmıştır. Eğer bir yanlışımı görürseniz kesinlikle ve kesinlikle beni uyarabilirsiniz.

    Geleneksel hale getirdiğim yazı sonu şarkısını aşağıya ekliyorum, bilimle kalın.

    https://www.youtube.com/watch?v=OYHsJ_h-noc

     

    https://enesergun.net/python-garbage-collection.html

     

    0x656e tarafından 06/Mar/19 15:49 tarihinde düzenlenmiştir
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    italyan
    italyan's avatar
    Kayıt Tarihi: 03/Aralık/2003
    Erkek

    En önemli şey aslında şu blog alışkanlığı insanlar böyle gelişiyor.Hem kendileri hem çevreleri hem toplum. Kaliteli bir toplumun tanıdığım bütün bilgi işçilerinin blogları var.
    Takip ediyorum yazılarını devam et hocam .


    Gerçek yoktur.Herşey yorumdur. - KKK - Düşünürseniz, acı çekersiniz. Şüphe ederseniz, delirirsiniz. Hissederseniz, yalnız kalırsınız. O yüzden koy goethe
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    TeRRoR
    TeRRoR's avatar
    Kayıt Tarihi: 06/Nisan/2007
    Erkek

    hocam eline sağlık. daha fazla kişiye erişebilmek açısından medium.com da da paylaşmanı öneririm. bizim tayfa çok fazla takılıyor oralarda.


    herkes programcı olmak zorunda değildir, lütfen bir zorunluluk gibi programlama dilleri öğrenmeye çalışmayın. yabancı dil filan öğrenin amq.// s.kimin etini yerim, kasaba minnet etmem.// ince düşünene kalın girer.//
  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    nick6
    0x656e
    0x656e's avatar
    Kayıt Tarihi: 19/Mayıs/2012
    Homo
    TeRRoR bunu yazdı

    hocam eline sağlık. daha fazla kişiye erişebilmek açısından medium.com da da paylaşmanı öneririm. bizim tayfa çok fazla takılıyor oralarda.

    selam hocam, medium'u sevmiyorum platform olarak o yüzden static site generator kullanıyorum. Daha fazla kişiye erişmek açısından problemim yok aslında rahat rahat erişebiliyorum. En azından siber güvenlik tarafında bu şekilde ilerliyor teşekkür ederim önerin için.

    @italyan teşekkür ederim hocam. Hem başkaları hemde benim için güzel bir not defteri oluyor aslında sadece düzenli halde yapmıyorum bunu. 

  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Zork.
    torpedo_XL
    torpedo_XL's avatar
    Kayıt Tarihi: 21/Ağustos/2005
    Erkek

    Emeğe sağlık +rep


    Bilge insanlar konuşurlar çünkü söyleyecek bir şeyleri vardır. Aptal insanlar konuşurlar çünkü bir şey söylemek zorundadırlar. Demokrasi, bir eğitim işidir. Eğitimsiz kitlelerle demokrasiye geçilirse oligarşi olur. Devam edilirse demagoglar türer. Demagoglardan da diktatörler çıkar. --Platon, Devlet                                                                                                                                                                                                                                                                                                                                                                                         
  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    nick6
    0x656e
    0x656e's avatar
    Kayıt Tarihi: 19/Mayıs/2012
    Homo
    torpedo_XL bunu yazdı

    Emeğe sağlık +rep

    ASudhasd şrfsz