JavaRush /Java Blog /Random-IT /Ciclo di vita dell'oggetto

Ciclo di vita dell'oggetto

Pubblicato nel gruppo Random-IT
Ciao! Penso che non sarai troppo sorpreso se ti diciamo che la dimensione della memoria del tuo computer è limitata :) Anche un disco rigido, che è molte volte più grande della RAM, può essere riempito con i tuoi giochi preferiti, serie TV, e così via. Per evitare che ciò accada, è necessario monitorare lo stato attuale della memoria ed eliminare i file non necessari dal computer. Cosa c'entra la programmazione Java con tutto questo? Diretto! Dopotutto, quando un oggetto viene creato dalla macchina Java, gli viene allocata memoria. In un programma davvero di grandi dimensioni vengono creati decine e centinaia di migliaia di oggetti, a ciascuno dei quali è allocata la propria porzione di memoria. Ciclo di vita dell'oggetto - 1Ma da quanto tempo pensi che esistano tutti questi oggetti? “Vivono” per tutto il tempo in cui il nostro programma è in esecuzione? Ovviamente no. Nonostante tutti i vantaggi degli oggetti Java, non sono immortali :) Gli oggetti hanno il proprio ciclo di vita. Oggi faremo una piccola pausa dalla scrittura del codice e osserveremo questo processo :) Inoltre, è molto importante per comprendere il funzionamento del programma e gestire le risorse. Allora, dove inizia la vita di un oggetto? Come una persona - dalla sua nascita, cioè la creazione.
Cat cat = new Cat();//вот сейчас и начался vital цикл нашего an object Cat!
Innanzitutto, la Java Virtual Machine alloca la quantità di memoria necessaria per creare l'oggetto. Quindi crea un collegamento ad esso, nel nostro caso, catper poterlo monitorare. Dopodiché, tutte le variabili vengono inizializzate, viene chiamato il costruttore ed ecco, il nostro nuovo oggetto sta già vivendo la propria vita :) La durata della vita degli oggetti è diversa, non ci sono numeri esatti qui. In ogni caso, da qualche tempo vive all'interno del programma e svolge le sue funzioni. Per essere precisi, un oggetto è “vivo” finché ci sono riferimenti ad esso. Non appena non rimangono più collegamenti, l'oggetto “muore”. Per esempio:
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;

   }

}
Nel metodo, main()l'oggetto vettura Lamborghini Diablo cessa di essere vivo già sulla seconda riga. C'era un solo collegamento ad esso e ora questo collegamento è stato assegnato null. Poiché non ci sono più riferimenti alla Lamborghini Diablo, diventa “spazzatura”. Non è necessario reimpostare il collegamento:
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;
   }

}
Qui abbiamo creato un secondo oggetto, dopodiché abbiamo preso il riferimento lamborghinie lo abbiamo assegnato a questo nuovo oggetto. Ora ci sono Lamborghini Gallardodue riferimenti all'oggetto, ma Lamborghini Diablonessuno all'oggetto. Pertanto l'oggetto Diablodiventa spazzatura. E in questo momento entra in funzione il meccanismo Java integrato chiamato Garbage Collector, o in altre parole Garbage Collector, GC.
Ciclo di vita dell'oggetto - 2
Il Garbage Collector è un meccanismo Java interno responsabile della liberazione della memoria, ovvero della rimozione da essa degli oggetti non necessari. Non per niente abbiamo scelto un'immagine con un robot aspirapolvere per rappresentarlo. Dopotutto, il garbage collector funziona più o meno allo stesso modo: in background “viaggia” attraverso il tuo programma, raccoglie la spazzatura e allo stesso tempo praticamente non interagisci con esso. Il suo compito è rimuovere gli oggetti che non vengono più utilizzati nel programma. Pertanto, libera memoria nel computer per altri oggetti. Ricordi che all'inizio della conferenza abbiamo detto che nella vita ordinaria devi monitorare lo stato del tuo computer ed eliminare i vecchi file? Quindi, nel caso degli oggetti Java, il garbage collector lo fa per te. Garbage Collector viene avviato più volte durante il funzionamento del programma: non è necessario richiamarlo specificatamente e impartirgli comandi, sebbene ciò sia tecnicamente possibile. Successivamente ne parleremo di più e analizzeremo il processo del suo lavoro in modo più dettagliato. Nel momento in cui il garbage collector raggiunge l'oggetto, subito prima della sua distruzione, viene chiamato sull'oggetto un metodo speciale - finalize(). Può essere utilizzato per liberare alcune risorse aggiuntive utilizzate dall'oggetto. Il metodo finalize()appartiene alla classe Object. Cioè, insieme a equals(), hashCode()e toString(), che hai già incontrato in precedenza, qualsiasi oggetto ce l'ha. La sua differenza rispetto agli altri metodi è che è... come dire... molto capriccioso. Vale a dire, non sempre viene chiamato prima di distruggere un oggetto. La programmazione è una cosa precisa. Il programmatore dice al computer di fare qualcosa e il computer lo fa. Probabilmente sei già abituato a questo comportamento e all'inizio potrebbe essere difficile per te accettare l'idea: “Prima che gli oggetti vengano distrutti, il metodo finalize()della classe si chiama Object. Oppure non è chiamato. Se siamo fortunati!" Tuttavia, questo è vero. La stessa macchina Java determina se chiamare il metodo finalize()in ciascun caso specifico o meno. Ad esempio, proviamo a eseguire il seguente codice a scopo di esperimento:
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;//вот здесь первый an object становится доступен сборщику мусора
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("Объект Cat уничтожен!");
   }
}
Creiamo un oggetto Cate nella riga di codice successiva reimpostiamo l'unico riferimento ad esso. E così - un milione di volte. Abbiamo sovrascritto esplicitamente il metodo finalize()e dovrebbe stampare la stringa sulla console un milione di volte, ogni volta prima di distruggere l'oggetto Cat. Ma no! Per essere precisi, sul mio computer è stato eseguito solo 37.346 volte! Cioè, solo in 1 caso su 27 la macchina Java che ho installato ha deciso di chiamare un metodo finalize(), negli altri casi la garbage collection è andata avanti senza questo. Prova tu stesso a eseguire questo codice: molto probabilmente il risultato sarà diverso. Come puoi vedere, finalize()è difficile definirlo un partner affidabile :) Pertanto, un piccolo consiglio per il futuro: non dovresti fare affidamento sul metodo finalize()nel caso di liberare alcune risorse critiche. Forse la JVM lo chiamerà, forse no. Chi lo sa? Se durante la sua vita il tuo oggetto ha occupato alcune risorse estremamente importanti per le prestazioni, ad esempio ha mantenuto una connessione aperta al database, è meglio creare un metodo speciale nella tua classe per liberarle e chiamarlo esplicitamente quando l'oggetto è non è più necessario. In questo modo saprai con certezza che le prestazioni del tuo programma non ne risentiranno. All'inizio abbiamo detto che la gestione della memoria e la rimozione dei rifiuti sono molto importanti, e questo è vero. La gestione inappropriata delle risorse e la mancanza di comprensione del processo di assemblaggio di oggetti non necessari possono portare a perdite di memoria. Questo è uno degli errori di programmazione più famosi. Il codice scritto in modo errato dal programmatore può comportare ogni volta l'allocazione di nuova memoria per gli oggetti appena creati, mentre gli oggetti vecchi e non necessari non sono disponibili per la rimozione da parte del Garbage Collector. Dato che abbiamo fatto un'analogia con un robot aspirapolvere, immagina cosa accadrebbe se, prima di avviare il robot, spargessi calzini per casa, rompessi un vaso di vetro e lasciassi un set Lego smontato sul pavimento. Il robot, ovviamente, proverà a fare qualcosa, ma ad un certo punto rimarrà bloccato.
Ciclo di vita dell'oggetto - 3
Perché funzioni correttamente, è necessario mantenere il pavimento in buone condizioni e rimuovere da lì tutto ciò che l'aspirapolvere non può assorbire. Il garbage collector funziona secondo lo stesso principio. Se nel programma rimangono molti oggetti che non può raccogliere (come un calzino o i Lego per un robot aspirapolvere), ad un certo punto la memoria si esaurirà. E non solo il programma che hai scritto si bloccherà, ma anche tutti gli altri programmi in esecuzione sul computer in quel momento. Non ci sarà abbastanza memoria neanche per loro. Questo è l'aspetto del ciclo di vita dell'oggetto e del garbage collector in Java. Non è necessario memorizzarlo: basta comprendere il principio di funzionamento. Nella prossima lezione parleremo di questi processi in modo più dettagliato, ma per ora puoi tornare a risolvere i problemi JavaRush :) Buona fortuna!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION