Introducere

Managementul memoriei este procesul de alocare, dezalocare și coordonare eficientă a memoriei, astfel încât toate procesele diferite să funcționeze fără probleme și să poată accesa în mod optim diferite resurse de sistem. Gestionarea memoriei implică, de asemenea, curățarea memoriei de obiectele care nu mai sunt accesate.

În Python, managerul de memorie este responsabil pentru aceste tipuri de sarcini prin rularea periodică pentru a curăța, aloca și gestiona memoria. Spre deosebire de C, Java și alte limbaje de programare, Python gestionează obiectele utilizând numărarea referințelor. Aceasta înseamnă că managerul de memorie ține evidența numărului de referințe la fiecare obiect din program. Atunci când numărul de referințe ale unui obiect scade la zero, ceea ce înseamnă că obiectul nu mai este utilizat, colectorul de gunoi (parte a managerului de memorie) eliberează automat memoria de la obiectul respectiv.

Utilizatorul nu trebuie să își facă griji cu privire la gestionarea memoriei, deoarece procesul de alocare și dezalocare a memoriei este complet automat. Memoria recuperată poate fi folosită de alte obiecte.

Python Garbage Collection

După cum s-a explicat mai devreme, Python șterge obiectele care nu mai sunt referite în program pentru a elibera spațiu de memorie. Acest proces prin care Python eliberează blocurile de memorie care nu mai sunt utilizate se numește Garbage Collection. Garbage Collector (GC) Python rulează în timpul execuției programului și este declanșat dacă numărul de referințe se reduce la zero. Numărul de referințe crește în cazul în care unui obiect i se atribuie un nume nou sau este plasat într-un container, cum ar fi tuple sau dicționare. În mod similar, numărul de referințe scade atunci când referința la un obiect este realocată, când referința obiectului iese din domeniul de aplicare sau când un obiect este șters.

Memoria este un heap care conține obiecte și alte structuri de date utilizate în program. Alocarea și dezalocarea acestui spațiu heap este controlată de managerul de memorie Python prin utilizarea funcțiilor API.

Obiecte Python în memorie

Care variabilă în Python acționează ca un obiect. Obiectele pot fi fie simple (care conțin numere, șiruri de caractere etc.), fie containere (dicționare, liste sau clase definite de utilizator). În plus, Python este un limbaj tipizat dinamic, ceea ce înseamnă că nu trebuie să declarăm variabilele sau tipurile lor înainte de a le folosi într-un program.

De exemplu:

Dacă vă uitați la primele 2 linii ale programului de mai sus, obiectul x este cunoscut. Când ștergem obiectul x și încercăm să îl folosim, primim o eroare care afirmă că variabila x nu este definită.

Vezi că garbage collection în Python este complet automatizată și programatorul nu trebuie să-și facă griji în legătură cu aceasta, spre deosebire de limbaje precum C.

Modificarea Garbage Collector

Garbage collector-ul Python are trei generații în care sunt clasificate obiectele. Un obiect nou la punctul de pornire al ciclului său de viață este prima generație a colectorului de gunoi. Pe măsură ce obiectul supraviețuiește colectării gunoiului, acesta va fi mutat în generațiile următoare. Fiecare dintre cele 3 generații ale colectorului de gunoi are un prag. Mai exact, atunci când este depășit pragul reprezentat de numărul de alocări minus numărul de0alocări, generația respectivă va rula colectarea de gunoi.

Generațiile anterioare sunt, de asemenea, colectate de gunoi mai des decât generațiile superioare. Acest lucru se datorează faptului că este mai probabil ca obiectele mai noi să fie aruncate decât obiectele vechi.

Modulul gc include funcții pentru a modifica valoarea pragului, a declanșa manual un proces de colectare a gunoiului, a dezactiva procesul de colectare a gunoiului etc. Putem verifica valorile de prag ale diferitelor generații ale colectorului de gunoi folosind metoda get_threshold():

import gcprint(gc.get_threshold())

Semplu de ieșire:

(700, 10, 10)

Cum vedeți, aici avem un prag de 700 pentru prima generație și 10 pentru fiecare dintre celelalte două generații.

Potem modifica valoarea pragului pentru declanșarea procesului de colectare a gunoiului folosind metoda set_threshold() a modulului gc:

gc.set_threshold(900, 15, 15)

În exemplul de mai sus, am crescut valoarea pragului pentru toate cele 3 generații. Creșterea valorii pragului va scădea frecvența de rulare a colectorului de gunoi. În mod normal, în calitate de dezvoltator, nu trebuie să ne gândim prea mult la colectarea gunoiului din Python, dar acest lucru poate fi util atunci când optimizăm timpul de execuție Python pentru sistemul țintă. Unul dintre beneficiile cheie este că mecanismul de colectare a gunoiului din Python se ocupă automat de o mulțime de detalii de nivel scăzut pentru dezvoltator.

De ce să efectuăm manual colectarea manuală a gunoiului?

Știm că interpretorul Python păstrează o evidență a referințelor la obiectele utilizate într-un program. În versiunile anterioare ale Python (până la versiunea 1.6), interpretul Python folosea doar mecanismul de numărare a referințelor pentru a gestiona memoria. Atunci când numărul de referințe scade la zero, interpretul Python eliberează automat memoria. Acest mecanism clasic de numărare a referințelor este foarte eficient, cu excepția faptului că nu reușește să funcționeze atunci când programul are cicluri de referințe. Un ciclu de referință are loc dacă unul sau mai multe obiecte sunt referite unul la altul și, prin urmare, numărul de referințe nu ajunge niciodată la zero.

Să luăm un exemplu.

>>> def create_cycle():... list = ... list.append(list)... return list... >>> create_cycle()]

Codul de mai sus creează un ciclu de referință, în care obiectul list se referă la el însuși. Prin urmare, memoria pentru obiectul list nu va fi eliberată automat la întoarcerea funcției. Problema ciclului de referință nu poate fi rezolvată prin numărarea referințelor. Cu toate acestea, această problemă a ciclului de referințe poate fi rezolvată prin schimbarea comportamentului colectorului de gunoi din aplicația Python.

Pentru a face acest lucru, putem folosi funcția gc.collect() din modulul gc.

import gcn = gc.collect()print("Number of unreachable objects collected by GC:", n)

Funcția gc.collect() returnează numărul de obiecte pe care le-a colectat și dezalocat.

Există două moduri de a efectua colectarea manuală a gunoiului: colectarea gunoiului pe bază de timp sau pe bază de evenimente.

Colectarea gunoiului pe bază de timp este destul de simplă: funcția gc.collect() este apelată după un interval de timp fix.

Colectarea gunoiului pe bază de eveniment apelează funcția gc.collect() după ce are loc un eveniment (de exemplu, atunci când aplicația este închisă sau când aplicația rămâne inactivă pentru o anumită perioadă de timp).

Să înțelegem cum funcționează colectarea manuală a gunoiului prin crearea câtorva cicluri de referință.

Lovitura de ieșire este cea de mai jos:

Creating garbage...Collecting...Number of unreachable objects collected by GC: 8Uncollectable garbage: 

Scriptul de mai sus creează un obiect listă care este referit de o variabilă, numită în mod creativ list. Primul element al obiectului listă se referă la el însuși. Numărul de referințe al obiectului listă este întotdeauna mai mare decât zero, chiar dacă acesta este șters sau în afara domeniului de aplicare în program. Prin urmare, obiectul list nu este colectat la gunoi din cauza referinței circulare. Mecanismul de colectare a gunoiului din Python va verifica automat și va colecta periodic referințele circulare.

În codul de mai sus, deoarece numărul de referințe este de cel puțin 1 și nu poate ajunge niciodată la 0, am colectat cu forța obiectele la gunoi prin apelarea gc.collect(). Cu toate acestea, nu uitați să nu forțați colectarea gunoiului în mod frecvent. Motivul este că, chiar și după eliberarea memoriei, GC are nevoie de timp pentru a evalua eligibilitatea obiectului pentru a fi colectat la gunoi, ceea ce consumă timp și resurse ale procesorului. De asemenea, nu uitați să gestionați manual garbage collector numai după ce aplicația dvs. a pornit complet.

Concluzie

În acest articol, am discutat despre modul în care gestionarea memoriei în Python este gestionată automat prin utilizarea strategiilor de numărare a referințelor și garbage collection. Fără garbage collection, implementarea unui mecanism reușit de gestionare a memoriei în Python este imposibilă. De asemenea, programatorii nu trebuie să-și facă griji cu privire la ștergerea memoriei alocate, deoarece de acest lucru se ocupă managerul de memorie Python. Acest lucru duce la mai puține scurgeri de memorie și la o performanță mai bună.

Lasă un răspuns

Adresa ta de email nu va fi publicată.