Distruge ssypki depășite (obiecte)

La trecerea de la o memorie de manual de limbaj de programare, cum ar fi C sau C ++, într-o limbă cu memorie de curățare automată (gunoi-colectare - „colectare!<а мусора") ваша работа как программиста существенно упрощается благодаря тому обстоятельству, что ваши объекты автоматически утилизируются, как только вы перестаете их использовать. Когда вы впервые сталкиваетесь с этой особенностью, то воспринимаете ее как волшебство. Легко может создаться впечатление, что вам больше не нужно думать об управлении’ памятью, но это не совсем так.

Luați în considerare următoarele punerea în aplicare simplă stiva:

// Poți să observați „scurgere de memorie“?

public class stivă

Obiect privat [] elemente;

size private int = 0;

publice stivă (int initialCapacity)

this.elements = new Object [initialCapacity];

public void împingere (Object e)

pop obiect publice ()

arunca nouă EmptyStackException ();

rezultat Obiect = elemente [: dimensiune];

elemente [size] = null; // Elimină referință învechite

* Să ne asigurăm că există o cameră de pe stivă și mai mult

* Pentru un singur element. de fiecare dată

* Necesitatea de a crește matrice, dublarea capacității sale.

ensureCapacity void privat ()

if (elements.length == dimensiune)

Object [] oldElements = elemente;

elemente = new Object [2 * elements.length + 1];

statice void main (String [] args) publice

Stiva s = new stivă (0);

pentru (int i = 0; i

pentru (int i = 0; i

În acest program nu există erori care ar prinde ochiul. Puteți să-l testa bine, va trece orice test un succes, dar există încă o problemă este ascunsă. În acest program, există o „scurgere de memorie“, care se poate manifesta în tăcere sub formă de productivitate a pierdut datorita performantelor sporite a colectorului de gunoi, sau sub formă de creștere a dimensiunii memoriei utilizate. Într-un caz extrem, o astfel de scurgere de memorie poate cauza paginare pe disc și chiar un accident cu diagnosticul OutOfMemoryError, cu toate că astfel de eșecuri sunt relativ rare.

pop obiect publice ()

arunca nouă EmptyStackException (); rezultat Obiect = elemente [: dimensiune];

elemente [size] = null; // Eliminați o legătură învechită

Resetarea trimiterilor caduce oferă un alt avantaj: dacă cineva din greșeală, atunci încercați să dereference oricare dintre aceste link-uri, programul se va încheia imediat cu NullRoiptegEhsertiop diagnostic în loc să efectueze operația în liniște greșită. Întotdeauna benefic pentru a detecta erorile fIrogrammirovaniya cât mai repede posibil.

Când programatori prima întâlnire o problemă similară, ele încep să fie reasigurate prin reducerea la zero toate trimiterile la obiecte, dar odată ce programul a terminat cu ei. Nu este necesar, deoarece programul de dezordine și reduce acestuia

Deci, atunci când ar trebui să resetați link-ul? Care caracteristică a clasei Stiva a făcut sensibile la pierderi de memorie? Clasa de stivă gestionează memoria sa. bazin de stocare constă dintr-o serie de elemente (și celulele sale sunt referiri la obiecte, nu înșiși obiecte). După cum sa menționat mai sus, elementele din partea activă a matrice folosită în restul - liber. Colectorul de gunoi știu acest lucru nu se poate, și pentru el toate referirile la obiectele care sunt stocate într-o matrice în egală măsură“valabil. Numai programator știe că nu este nevoie de partea inactivă a matricei. Raportează acest programator colector de gunoi poate reseta numai manual elementele de matrice în care acestea se deplasează în porțiunea non-activă a matrice.

În general vorbind, în cazul în care o clasă începe să gestioneze memoria lor, programatorul trebuie să se gândească la o scurgere de memorie. Odată ce elementul de matrice este eliberat, orice referiri la obiecte care au existat în acest element trebuie să fie resetat.

O altă sursă comună de cache-uri de memorie scurgeri de informații. Plasarea unul din link-ul de cache la un obiect, este ușor să uităm că este acolo, și să păstreze legătura în cache pentru o lungă perioadă de timp după ce a devenit invalid. Există două soluții posibile pentru această problemă. Dacă se întâmplă să creați un cache în care înregistrarea este semnificativă exact atâta timp cât exteriorul cache sunt link-uri pentru a-cheie, imagina cum acest cache WeakHashMap: atunci când înregistrările sunt depășite, acestea vor fi șterse automat. În general, timpul în care intrarea cache este semnificativă. nu este specificat în mod clar. Intrările își pierd relevanța lor în timp. În astfel de circumstanțe, cache-ul ar trebui să fie curățate ocazional de înregistrări pe care nimeni nu le folosește. O astfel de curățare poate efectua cakground (de exemplu, prin intermediul API java.util. Titeg), sau poate fi un efect secundar de a adăuga noi intrări în memoria cache. Atunci când cea de a doua abordare este utilizată în metoda clasei removeEldestEntry java.util.LinkedHashMap, inclus în versiunea 1.4.

Deoarece scurgere de memorie nu se manifestă, de obicei, sub formă de eșec aparent, acesta poate rămâne în sistemul de ani de zile. De obicei, detectat numai într-o inspecție amănunțită a codului sau prin utilizarea unui instrument de depanare, cunoscut ca un formatorul (profiler heap). Prin urmare, este foarte important să învețe să anticipeze probleme ca acest lucru înainte ca acestea să apară, și pentru a preveni apariția lor.

Sursa: Dzhoshua Bloh, Java TM eficienta de programare, Editura "Lori"