Secondo il sondaggio Stackoverflow del 2019, il linguaggio di programmazione Python ha ottenuto il 73,1% di approvazione tra gli sviluppatori. È al secondo posto per Rust e continua a dominare nella scienza dei dati e nell’apprendimento automatico(ML).
Python è uno dei preferiti degli sviluppatori. È un linguaggio di alto livello noto per la sua robustezza e la sua filosofia di base: la semplicità rispetto alla complessità. Tuttavia, le prestazioni dell’applicazione Python è un’altra storia. Proprio come qualsiasi altra applicazione, ha la sua quota di problemi di prestazioni.
La maggior parte delle volte, gli strumenti APM come Retrace possono aiutare a risolvere i problemi di prestazioni delle applicazioni. Ma cosa succede se la tua applicazione Python è in esecuzione da quattro ore e il server ha esaurito la memoria? Questo è un problema specifico che coinvolge le risorse di memoria.
Si chiama perdita di memoria. Gli sviluppatori devono trovare il colpevole. Questo è quando Python memory profilers entra in gioco.
Esploriamo ulteriormente.
Che cosa sono i profiler di memoria Python?
Le applicazioni di profilazione comportano sempre problemi come CPU,memoria, ecc. Tuttavia, le applicazioni Python sono soggette a problemi di gestione della memoria. Questo è principalmente perché Python viene applicato alla scienza dei dati e applicazioni ML e funziona con grandi quantità di dati. Inoltre, Python si basa sul suo sistema di gestione della memoria per impostazione predefinita, invece di lasciarlo all’utente.
Poiché il codice Python funziona all’interno di contenitori tramite un framework di elaborazione distribuito, ogni contenitore contiene una quantità fissa di memoria. Se l’esecuzione del codice supera il limite di memoria, il contenitore terminerà. Questo è quando lo sviluppo sperimenta errori di memoria.
Tuttavia, non è sempre il caso. Ci sono casi in cui gli sviluppatori non sanno cosa sta succedendo. Forse un oggetto è appeso a un riferimento quando non dovrebbe essere e si accumula nel tempo. Una volta raggiunto il suo picco, si verificano problemi di memoria.
La soluzione rapida consiste nell’aumentare l’allocazione della memoria. Tuttavia, non è pratico in quanto ciò potrebbe comportare uno spreco di risorse. Inoltre, potrebbe compromettere la stabilità dell’applicazione a causa di picchi di memoria imprevedibili.
Quindi, abbiamo bisogno dell’aiuto dei profiler di memoria Python. Lo scopo dei profiler di memoria Python è trovare perdite di memoria e ottimizzare l’utilizzo della memoria nelle applicazioni Python. Questi tipi di profiler di memoria Python comprendono l’efficienza dello spazio del codice e dei pacchetti utilizzati.
Top Python Memory Profilers
Sebbene Python gestisca automaticamente la memoria, ha bisogno di strumenti perché i lavori Python di lunga durata consumano molta memoria. Nella maggior parte dei casi, questi lavori non restituiranno la memoria al sistema operativo fino alla fine del processo, anche se esegue correttamente la garbage collection.
Ecco un elenco di noti profiler di memoria Python:
Pympler
Jean Brouwers, Ludwig Haehne e Robert Schuppenies costruirono Pympler nell’agosto 2008. Hanno introdotto il processo di pympling, in cui Pympler ottiene dettagli della dimensione e della durata degli oggetti Python.
Python memory profiler di Pympler analizza il comportamento della memoria dell’oggetto Python all’interno di un’applicazione in esecuzione. Fornisce una soluzione di profilazione della memoria Python completa e stand-alone. Inoltre, proietta possibili errori nel comportamento di runtime come il gonfiore della memoria e altri “pymples”.”
Ci sono tre moduli separati all’interno di Pympler.
- Il modulo asizeof fornisce le informazioni sulle dimensioni dell’oggetto Python.
- Il modulo muppy si rivolge al monitoraggio on-line di un’applicazione Python.
- Il modulo Class Tracker fornisce un’analisi off-line della durata degli oggetti Python selezionati.
Per prima cosa, usiamo asizeof per indagare su quanta memoria consumano determinati oggetti Python.
>>> from pympler import asizeof
>>> obj =
>>> asizeof.asizeof(obj)
>>> print (asizeof.asized(obj, detail=1).format())
size=192 flat=48
(6, 4)=64 flat=32
” io ” size=32 flat=32
3 size=16 flat=16
2 size=16 flat=16
1 size=16 flat=16
Secondo, implementiamo il muppy modulo:
>>> da pympler importazione muppy
>>> allObjects = muppy.get_objects()
>>> len(allObjects)
>>> da pympler riepilogo di importazione
>>> I = riepilogo.per ulteriori informazioni, consultare il sito:
types | | # objects | | total size |
========================== | | =========== | | ============ |
str | | 13262 | | 1.01 MB |
dict | | 2120 | | 659.99 KB |
code | | 3362 | | 343.73 KB |
list | | 2587 | | 247.46 KB |
type | | 639 | | 242.61 KB |
tuple | | 2069 | | 58.83 KB |
set | | 86 | | 44.57 KB |
wrapper_descriptor | | 1247 | | 43.84 KB |
builtin_function_or_method | | 1014 | | 35.65 KB |
method_descriptor | | 937 | | 32.94 KB |
abc.ABCMeta | | 66 | | 32.38 KB |
weakref | | 818 | | 28.76 KB |
int | | 1612 | | 24.72 KB |
getset_descriptor | | 555 | | 17.34 KB |
frozenset | | 90 | | 16.87 KB |
Qui, è possibile visualizzare tutti gli oggetti Python in un mucchio utilizzando il muppy modulo. È possibile chiamare un altro riepilogo e confrontarlo per verificare se alcuni array hanno perdite di memoria. Scopri di più sul modulo muppy qui.
Il terzo modulo nel Pympler profiler è il Class Tracker. Tiene traccia della durata degli oggetti di determinate classi. Thus, it provides insight into instantiation patterns and helps developers understand how specific objects contribute to the memory footprint in the long run.
>>> tr = classtracker.ClassTracker()
>>> tr.track_class(Document)
>>> tr.create_snapshot(description=’Snapshot 1′)
>>> doc = create_document()
>>> tr.create_snapshot(description=’Snapshot 2′)
>>> tr.stats.print_summary ()
SUMMARY SOMMARIO ———————-
Istantanea 1 attivo 0 B pct medio
Istantanea 2 attivo 0 B pct medio
—————————
Per saperne di più su Class Tracker, clicca qui.
Guppy3
Guppy3 (noto anche come Heapy) è un ambiente di programmazione Python e un set di strumenti di analisi heap. È un pacchetto che contiene i seguenti sotto-pacchetti:
- ecc – Questo è un modulo di supporto che ha il modulo di protocollo Glue.
- gsl-Il subpackage che contiene l’implementazione del linguaggio delle specifiche Guppy. Crea documenti e test da una fonte comune.
- heapy – Il set di strumenti di analisi heap fornisce informazioni sugli oggetti sull’heap e visualizza le informazioni.
- sets-Contiene Bitset e nodeset.
Guppy3 è un fork di Guppy-PE ed è stato costruito da Sverker Nilsson per Python 2.
Nota: l’utilizzo di questo profiler di memoria Python richiede Python 3.5, 3.6, 3.7 o 3.8. Questo pacchetto funziona solo per CPython. Quindi, PyPy e altre implementazioni del compilatore Python non sono supportate. Inoltre, per utilizzare il browser grafico, ha bisogno di Tkinter. Inoltre, la filettatura deve essere disponibile quando si utilizza un monitor remoto.
Ecco come sfruttare questo profiler di memoria Python. È possibile scattare un’istantanea dell’heap prima e dopo un processo critico. Quindi confrontare la memoria totale e individuare possibili picchi di memoria coinvolti all’interno di oggetti comuni.
>>> from guppy import hpy
>>> h=hpy()
>>> h.heap()
Partition of a set of 34090 objects. Total size = 2366226 bytes.
Index | Count | % | Size | % | Cumulative | % | Kind (class / dict of class) |
0 | 10279 | 30 | 666873 | 28 | 666873 | 28 | str |
1 | 4697 | 14 | 259576 | 11 | 926449 | 39 | bytes |
2 | 2413 | 7 | 251684 | 11 | 1178133 | 50 | types.CodeType |
3 | 6825 | 20 | 238084 | 10 | 1416217 | 60 | tuple |
4 | 448 | 1 | 174868 | 7 | 1591085 | 67 | type |
5 | 2208 | 6 | 150144 | 6 | 1741229 | 74 | function |
6 | 448 | 1 | 130964 | 6 | 1872193 | 79 | dict of type |
7 | 94 | 0 | 83532 | 4 | 1955725 | 83 | dict of module |
8 | 242 | 1 | 56524 | 2 | 2012249 | 85 | dict (no owner) |
9 | 1133 | 3 | 40788 | 2 | 2053037 | 87 | types.WrapperDescriptorType |
<118 more rows. Type e.g. ‘_.more’ to view.>
Memory Profiler
Memory Profiler is a pure Python module that uses the psutil module. Monitora il consumo di memoria di un processo di lavoro Python. Inoltre, esegue un’analisi riga per riga del consumo di memoria dell’applicazione.
La modalità di utilizzo della memoria riga per riga funziona allo stesso modo di line_profiler.
- Decora la funzione che si desidera profilare utilizzando la funzione @profile.
- È possibile eseguire lo script con uno script speciale. Ad esempio, utilizzare argomenti specifici per l’interprete Python.
Nell’esempio seguente, abbiamo una semplice funzione chiamata my_func. Questa funzione crea un elenco con un intervallo specificato.
@profile
def my_func():
a=
for i in range(1000):
a.append(i)
my_func()
This outputs:
Line # | Mem Usage | Increment | Line Contents |
1 | 13.859 MiB | 13.859 MiB | @profile |
2 | def my_func(): | ||
3 | 13.859 MiB | 0.000 MiB | a= |
4 | 13.859 MiB | 0.000 MiB | for i in range(1000): |
5 | 13.859 MiB | 0.000 MiB | un.append(i) |
La prima colonna è il numero di riga del profilato codice. L’utilizzo Mem è l’utilizzo della memoria dell’interprete Python dopo ogni esecuzione di codice. La terza colonna (Incremento) rappresenta la differenza di memoria tra la riga corrente e l’ultima. L’ultima colonna (Contenuto riga) visualizza i codici profilati.
To see how this Python memory profiler works, let’s change the range value to 1000000 in the function above and execute it. Here is the output:
Line # | Mem usage | Increment | Line Contents |
1 | 13.844 MiB | 13.844 MiB | @profile |
2 | def my_func(): | ||
3 | 13.844 MiB | 0.000 MiB | a= |
4 | 33.387 MiB | 0.016 MiB | for i in range(1000000): |
5 | 33.387 MiB | 0.293 MiB | un.append(i) |
la Linea 4 e 5 mostrano un aumento di utilizzo della memoria, dimostrando che profiler esegue una linea di analisi del consumo di memoria.
Fil
Fil profiler è un profiler di memoria Python open-source. È adatto per l’elaborazione dei dati e applicazioni di calcolo scientifico. Attualmente, è ancora in fase di sviluppo e funziona solo su Linux e macOS.
La maggior parte dei Data Scientist e degli sviluppatori Python affrontano problemi di memoria con la pipeline di dati Python. Quando si utilizza troppa memoria, è difficile individuare dove esattamente tutta la memoria sta andando.
Ad esempio, citiamo due scenari:
Server
Poiché i server sono in esecuzione senza interruzioni, le perdite di memoria sono spesso la causa dell’errore delle prestazioni. Gli sviluppatori trascurano piccole quantità di perdite di memoria poiché la maggior parte dei server elabora piccole quantità di dati alla volta. Tuttavia, questi possono aggiungere fino a decine di migliaia di chiamate. Di conseguenza, ciò potrebbe creare gravi problemi di produzione nel tempo.
Pipeline di dati
Quando si elaborano blocchi di dati di grandi dimensioni, i picchi di utilizzo della memoria portano enormi minacce alle pipeline di dati. Ad esempio, se l’applicazione utilizza 1 GB di RAM per un bel po ‘ di tempo e poi improvvisamente ha bisogno di 16 GB di RAM. C’è un grande bisogno di identificare ciò che causa improvvisi picchi di memoria.
Questo è l’obiettivo principale di Fil: diagnosticare i picchi di utilizzo della memoria, indipendentemente dalla quantità di dati elaborati. Individua esattamente dove si trova il picco di utilizzo della memoria e quale codice è responsabile di quel picco.
Sebbene esistano profiler di memoria Python che misurano l’utilizzo della memoria, ha delle limitazioni. Uno dei quali si occupa di grandi quantità di elaborazione dei dati in batch. Le applicazioni Python sono per lo più applicazioni di elaborazione batch in cui leggono costantemente i dati, li elaborano e producono il risultato.
Questo problema viene risolto dal nostro prossimo profiler.
Blackfire
Per un linguaggio altamente dinamico come Python, la maggior parte degli sviluppatori riscontrano problemi di memoria durante la distribuzione. Ciò porta a una certa confusione su ciò che accade all’utilizzo della memoria. Gli sviluppatori tendono a eseguire ottimizzazioni ma non hanno gli strumenti giusti da utilizzare.
Blackfire è un profiler di memoria Python proprietario (forse il primo. Utilizza Memory manager di Python per tracciare ogni blocco di memoria allocato da Python, incluse le estensioni C. Blackfire è nuovo nel campo e mira a risolvere problemi di perdite di memoria come:
- oggetti di grandi dimensioni in memoria non disponibile
- riferimento cicli
- non valido il conteggio dei riferimenti in C estensioni causando perdite di memoria
- ricordo improvviso spike
Con questi casi di utilizzo, Blackfire garantisce agli utenti che è molto limitato il sovraccarico e non influenza gli utenti finali, dato che misura l’applicazione Python il consumo di memoria alla chiamata di funzione di livello.
Blackfire Python memory profiler utilizza PyMem_SetAllocator API per tracciare le allocazioni di memoria come tracemalloc. Al momento, Blackfire supporta le versioni Python 3.5 e successive. Puoi visitare il suo sito per saperne di più.
Profiling with Retrace
Se stai lavorando con Python, in qualche modo provi che non rilascia immediatamente la memoria nel sistema operativo. Pertanto, lo si esegue in un processo separato per garantire che la memoria venga rilasciata dopo l’esecuzione di un pezzo di codice. Questo viene fatto attraverso un approccio utile chiamato ” small test case.”Questo processo consente di eseguire solo il codice di perdita di memoria in questione.
Quando si ha a che fare con grandi quantità di dati, utilizzare un sottoinsieme dei dati campionati in modo casuale. Inoltre, eseguire attività ad alta intensità di memoria in processi separati e utilizzare i debugger per aggiungere riferimenti agli oggetti. Tuttavia, considerare che l’utilizzo di un debugger punto di interruzione come pdb consente a tutti gli oggetti creati e referenziati manualmente dal debugger di rimanere nel profilo di memoria. Ciò si tradurrà in un falso senso di perdite di memoria poiché gli oggetti non vengono rilasciati in tempo. Inoltre, considera di esaminare i pacchetti che possono perdere. Ci sono librerie Python che potrebbero potenzialmente avere perdite di memoria.
Ormai, sai già come funzionano i profiler di memoria Python e i comuni problemi di memoria con Python. Ma strumenti come Retrace con registrazione centralizzata, monitoraggio degli errori e profilazione del codice possono aiutarti a diagnosticare i problemi di Python su scala più ampia. Retrace da Stackify ti aiuterà ad affrontare qualsiasi tipo di insidie in termini di prestazioni e a mantenere il tuo codice in esecuzione.
Inizia la tua prova GRATUITA di 14 giorni oggi!