2012-08-09 13 views
15

cosa è un buon modo per trovare tutti i riferimenti a un oggetto in Python?Trova tutti i riferimenti a un oggetto in pitone

Il motivo che mi chiedo è che sembra che abbiamo una "perdita di memoria". Stiamo caricando file di immagine sul server da un browser web. Ogni volta che lo facciamo, l'utilizzo della memoria sale sul server sale proporzionalmente alla dimensione del file appena caricato. Questa memoria non viene mai rilasciata dalla garbage collection di Python, quindi penso che ci siano probabilmente dei riferimenti vaganti che puntano ai dati dell'immagine che non vengono cancellati o che non escono dall'ambito, anche alla fine di ogni richiesta.

immagino che sarebbe bello essere in grado di chiedere pitone: "Quali riferimenti sono ancora rivolte a questa memoria" in modo che possa capire cosa trattiene la raccolta dei rifiuti dalla sua liberazione.

Attualmente ci sono in esecuzione Python e Django su un server di Heroku.

Tutti i suggerimenti e le idee sono apprezzati, grazie mille!

+0

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

+0

Hai guardato questo: http://stackoverflow.com/questions/110259/python-memory-profiler –

risposta

10

libreria standard di Python ha gc modulo contenente garbage collector API. Una delle funzioni che si desidera avere è

gc.get_objects() 

Questa funzione restituisce l'elenco di tutti gli oggetti attualmente tracciati dal garbage collector. Il prossimo passo è analizzarlo.

Se si conosce l'oggetto che si desidera tenere traccia è possibile utilizzare la funzione sys del modulo getrefcount: Modulo

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

sys.getrefcount() è utile, ma esiste un modo per vedere quali sono questi riferimenti? – RAAC

12

di Python gc ha diverse funzioni utili, ma suona come gc.get_referrers() è quello che stai cercando. Ecco un esempio:

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 

Quando eseguo che, vedo il seguente output:

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

Si può vedere che la prima linea è l e d, e la seconda linea è solo l.

Nei miei brevi esperimenti, ho trovato che i risultati non sono sempre così pulita. Stringhe e tuple internate, ad esempio, hanno più referrer di quanti te ne aspetterei.

+1

Questa sembra la risposta più semplice e migliore. –

Problemi correlati