CodeGym /Blog Java /Aleatoriu /Ciclul de viață al obiectului
John Squirrels
Nivel
San Francisco

Ciclul de viață al obiectului

Publicat în grup
Bună! Cred că nu ai fi foarte surprins dacă ți-aș spune că computerul tău are o cantitate limitată de memorie :)
Ciclul de viață al obiectului - 1
Chiar și hard disk-ul tău (care este de multe ori mai mare decât memoria RAM) poate fi plin de jocurile, emisiunile TV și alte lucruri preferate. Pentru a preveni acest lucru, trebuie să monitorizați starea curentă a memoriei computerului și să ștergeți fișierele inutile. Cum se leagă toate acestea de programarea Java? Destul de direct! La urma urmei, crearea oricărui obiect face ca mașina Java să aloce memorie pentru acesta . Un program mare din lumea reală creează zeci sau sute de mii de obiecte și o bucată de memorie este alocată pentru fiecare dintre ele. Dar ce crezi, câte dintre aceste obiecte există? Sunt ei „vii” în timp ce programul nostru rulează? Desigur că nu. Chiar și cu toate avantajele lor, obiectele Java nu sunt nemuritoare :) Obiectele au propriul ciclu de viață. Astăzi vom face o mică pauză de la scrierea codului și vom explora acest proces :) Este, de asemenea, foarte important pentru înțelegerea modului în care funcționează un program și pentru gestionarea resurselor. Deci, de unde începe viața unui obiect? Ca un om, de la naștere, adică atunci când este creat.

Cat cat = new Cat();// Our Cat object's lifecycle begins now!
În primul rând, mașina virtuală Java alocă memoria necesară pentru a crea obiectul. Apoi creează o referință la acesta (în cazul nostru, cat) pentru a face posibilă urmărirea acesteia. Apoi toate variabilele sunt inițializate, constructorul este apelat și obiectul nostru proaspăt își trăiește acum propria viață :) Duratele de viață ale obiectului variază. Nu există cifre exacte aici. În orice caz, un obiect locuiește în program și își îndeplinește funcțiile pentru o anumită perioadă de timp. Mai exact, obiectul este „viu” atâta timp cât există referiri la el. De îndată ce nu există referințe, obiectul „moare”. De exemplu:

public class Car {
  
   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
În main()metodă, obiectul Mașină „Lamborghini Diablo” încetează să mai fie viu pe a doua linie. A existat o singură referință la acesta, iar referința a fost setată la nul. Deoarece nu au mai rămas referințe la Diablo, acesta devine „gunoi”. O referință nu trebuie să fie setată la zero pentru ca acest lucru să se întâmple:

public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
Aici am creat un al doilea obiect și l-am atribuit referinței lamborghini. Acum două referințe indică obiectul Lamborghini Gallardo, dar Lamborghini Diabloobiectul nu are niciuna. Aceasta înseamnă că Diabloobiectul devine gunoi. Acesta este momentul în care intervine colectorul de gunoi (GC) încorporat în Java .
Ciclul de viață al obiectului - 2
Garbage Collector este un mecanism intern Java responsabil de eliberarea memoriei, adică de eliminarea obiectelor inutile din memorie. Există un motiv pentru care am ales să-l reprezentăm cu un robot aspirator. Colectorul de gunoi funcționează aproximativ în același mod: se „mișcă” programul tău în fundal, adunând gunoiul. Practic nu trebuie să interacționezi cu el. Sarcina sa este de a șterge obiectele care nu mai sunt folosite în program. Astfel, eliberează memorie pentru alte obiecte. Îți amintești că la începutul lecției am spus în viața reală că trebuie să monitorizezi starea computerului și să ștergi fișierele vechi? Dacă vorbim despre obiecte Java, colectorul de gunoi face acest lucru pentru tine. Colectorul de gunoi este pornit de multe ori pe măsură ce programul dumneavoastră rulează: nu trebuie să îl apelați în mod explicit și să îi dați comenzi (deși acest lucru este posibil din punct de vedere tehnic). Vom vorbi mai multe despre colectorul de gunoi mai târziu și vom analiza mai detaliat cum funcționează. Când colectorul de gunoi ajunge la un obiect - chiar înainte de a fi distrus - metoda specială a obiectului finalize()este apelată. Această metodă poate fi invocată pentru a elibera anumite resurse suplimentare utilizate de obiect. Metoda finalize()aparține clasei Object. Cu alte cuvinte, este similar cu equals(), hashCode()și toString()(pe care le-ați întâlnit anterior). Fiecare obiect o are . Diferă de alte metode prin faptul că... cum ar trebui să spunem asta... este foarte intenționat. Prin asta ne referim la astanu este întotdeauna numit înainte ca un obiect să fie distrus . Programarea este o activitate foarte precisă. Programatorul îi spune computerului să facă ceva, iar computerul o face. Presupun că te-ai obișnuit cu acest tip de comportament, așa că la început ți-ar putea fi dificil să accepți următoarea idee: „Înainte de a fi distrus un obiect, se numește metoda clasei Object. Sau nu. finalize()Dacă avem noroc! " Totuși, aceasta este realitatea. Mașina Java însăși determină dacă să apeleze finalize() de la caz la caz. Ca experiment, să încercăm să rulăm următorul cod:

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;// The first object becomes available for garbage collection here
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("The Cat is destroyed!");
   }
}
Creăm un Catobiect, iar în linia următoare eliminăm singura referință la el. Și facem asta de un milion de ori. Am suprascris în mod explicit finalize()metoda. De fiecare dată când un Catobiect este distrus, acesta trebuie să afișeze un șir – în total de un milion de ori. Dar nu! Mai exact, pe computerul meu a fost executat doar de 37346 de ori! Cu alte cuvinte, mașina mea Java a decis să apeleze finalize()metoda doar în 1 din 27 de cazuri. În celelalte cazuri, colectarea gunoiului nu a implicat acest apel. Încercați să rulați singur acest cod. Cel mai probabil veți obține un rezultat diferit. După cum puteți vedea, este greu să apelați finalize()un partener de încredere :) Așadar, iată un mic sfat pentru viitor: nu vă bazați pe finalize()metoda de a elibera resurse critice.JVM-ul ar putea să-l numească sau s-ar putea să nu. Cine ştie? Dacă obiectul dvs. a deținut unele resurse critice pentru performanță (de exemplu, o conexiune de bază de date deschisă) cât timp a fost în viață, ar fi mai bine să creați și să apelați în mod explicit o metodă specială pentru a le elibera atunci când obiectul nu mai este necesar. În acest fel, veți ști sigur că performanța programului dvs. nu va avea de suferit. Am început prin a spune că lucrul cu memoria și colectarea gunoiului sunt subiecte foarte importante și, într-adevăr, sunt. Manevrarea greșită a resurselor și înțelegerea greșită a modului în care obiectele inutile sunt curățate poate duce la unul dintre cele mai neplăcute erori: scurgeri de memorie . Aceasta este una dintre cele mai cunoscute erori de programare. Are chiar și propriul articol Wikipedia. Codul scris prost poate crea o situație în care memoria este alocată de fiecare dată pentru obiectele nou create, dar obiectele vechi, inutile, nu sunt disponibile pentru colectarea gunoiului. Deoarece am făcut deja o analogie cu aspiratorul robot, imaginați-vă ce s-ar întâmpla dacă înainte de a rula robotul ați împrăștiat șosete prin toată casa, ați spart o vază de sticlă și ați lăsa piese Lego pe podea. Desigur, robotul ar încerca să facă ceva, dar într-o zi se va prinde.
Ciclul de viață al obiectului - 3
Pentru ca aspiratorul să funcționeze corect, trebuie să păstrați podeaua într-o formă decentă și să ridicați tot ceea ce nu poate face față. Colectorul de gunoi urmează același principiu. Dacă un program are o mulțime de obiecte pe care nu le poate curăța (cum ar fi un șosetă sau Lego pentru aspiratorul nostru robot), într-o zi vom rămâne fără memorie. Nu numai că programul tău se va bloca, ci și toate celelalte programe care se întâmplă să ruleze pe computer. Până la urmă, nici ei nu vor avea suficientă memorie (revenind la analogia noastră, geamul spart de pe jos oprește nu doar aspiratorul, ci și oamenii care locuiesc în casă). Pe scurt, așa arată ciclul de viață al obiectelor și colectarea gunoiului în Java. Nu trebuie să memorați asta: este suficient să înțelegeți pur și simplu cum funcționează. În următoarea lecție, noi Voi reveni la aceste procese mai detaliat. Dar, deocamdată, puteți reveni la rezolvarea sarcinilor CodeGym :) Succes!
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION