2012-08-09 32 views
15

Python'da nesneye yapılan tüm başvuruları bulmanın iyi bir yolu nedir?python içindeki bir nesneye yapılan tüm referansları bul

Sormamın nedeni, bir "bellek sızıntısı" yaptığımıza benzemesidir. Görüntü dosyalarını sunucuya bir web tarayıcısından yüklüyoruz. Bunu her yaptığımızda, sunucudaki bellek kullanımı artar, yüklenen dosyanın boyutuna orantılı olarak yükselir. Bu hafıza python çöp toplama tarafından asla serbest bırakılmıyor, bu yüzden muhtemelen her bir isteğin sonunda bile silinmeyen veya kapsam dışı bırakılan görüntü verisini işaret eden baştan aşağı referansların olduğunu düşünüyorum.

Python'a sormak güzel olurdu: "Bu hafızayı hala işaret eden referanslar nedir?" Böylece çöp koleksiyonunun neyi serbest bıraktığını anlayabiliyorum.

Şu anda bir Heroku sunucusunda Python ve Django kullanıyoruz.

Her türlü öneri ve fikir takdir edildi, çok teşekkürler!

+0

http://stackoverflow.com/questions/1339293/python-memory-leak-debugging –

+0

bu baktınız mı: http://stackoverflow.com/questions/110259/python-memory-profiler –

cevap

10

Python'un standart kitaplığı, çöp toplayıcı API'si içeren gc modülüne sahiptir. Eğer mümkün olmasını istediğiniz fonksiyonu biri

gc.get_objects() 

Bu fonksiyon şu anda çöp toplayıcı tarafından izlenen tüm nesnelerin listesini döndürür olduğunu. Bir sonraki adım, onu analiz etmektir.

size sys modülün getrefcount fonksiyonunu kullanabilirsiniz izlemek istediğiniz nesneyi biliyorsanız:

>>> x = object() 
>>> sys.getrefcount(x) 
2 
>>> y = x 
>>> sys.getrefcount(x) 
3 
+9

sys.getrefcount() yararlıdır, ancak bu referansların ne olduğunu görmenin bir yolu var mı? – RAAC

12

Python'un gc modül birçok yararlı işlevleri vardır, ancak gc.get_referrers() aradığınız ne gibi geliyor. İşte bir örnek:

[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}] 
[[[2, 4, 6], [1, 4, 7]]] 

İlk çizgi l ve d, ve ikinci sıra sadece l olduğunu görebilirsiniz:

import gc 


def foo(): 
    a = [2, 4, 6] 
    b = [1, 4, 7] 

    l = [a, b] 
    d = dict(a=a) 
    return l, d 

l, d = foo() 
r1 = gc.get_referrers(l[0]) 
r2 = gc.get_referrers(l[1]) 

print r1 
print r2 

Ben şu çıktıyı görmek koşmak

.

Kısa denemelerimde, sonuçların her zaman bu kadar temiz olmadığını fark ettim. Örneğin, dahili dizeler ve kopyalar, beklediğinizden daha fazla yönlendiriciye sahiptir.

+1

Bu en basit ve en iyi yanıt olarak görünüyor. –

İlgili konular