Gestione della memoria in Java
Cos'è la memoria dello stack?
Lo stack in Java è una sezione di memoria che contiene metodi, variabili locali e variabili di riferimento. Si fa sempre riferimento alla memoria dello stack nell'ordine Last-In-First-Out. Le variabili locali vengono create nello stack.
Cos'è la memoria heap?
L'heap è una sezione di memoria che contiene oggetti e può anche contenere variabili di riferimento. Le variabili di istanza vengono create nell'heap.
Allocazione memoria in Java
Allocazione memoria in Java è il processo in cui le sezioni di memoria virtuale vengono riservate in un programma per memorizzare le variabili e le istanze di strutture e classi. Tuttavia, la memoria non viene allocata a un oggetto al momento della dichiarazione ma viene creato solo un riferimento. Per l'allocazione della memoria dell'oggetto, viene utilizzato il metodo new(), quindi all'oggetto viene sempre allocata memoria nell'heap.
Java L'allocazione della memoria è suddivisa nelle seguenti sezioni:
- Heap
- pila
- Code
- statica
Questa divisione della memoria è necessaria per la sua gestione efficace.
- codice contiene il tuo codice a byte.
- pila sezione della memoria contiene metodi, variabili locali e variabili di riferimento.
- Heap sezione contiene Oggetti (può contenere anche variabili di riferimento).
- statica sezione contiene Dati/metodi statici.
Differenza tra variabile locale e di istanza
Variabile di istanza è dichiarato all'interno di una classe ma non all'interno di un metodo
class Student{ int num; // num is instance variable public void showData{}
Variabile locale sono dichiarati interno a metodo compreso metodo argomenti.
public void sum(int a){ int x = int a + 3; // a , x are local variables; }
Differenza tra Stack e Heap
Clicchi qui se il video non è accessibile
Facciamo un esempio per capirlo meglio. Considera che il tuo metodo principale chiama il metodo m1
public void m1{ int x=20 }
Nello stack Java, verrà creato un frame dal metodo m1.
Anche la variabile X in m1 verrà creata nel frame per m1 nello stack. (Vedi immagine sotto).
Il metodo m1 chiama il metodo m2. Nello stack Java, viene creato un nuovo frame per m2 sopra il frame m1.
Anche le variabili b e c verranno create in un frame m2 in uno stack.
public void m2(int b){ boolean c; }
Lo stesso metodo m2 richiama il metodo m3. Di nuovo, un frame m3 viene creato in cima allo stack (vedi immagine sotto).
Ora supponiamo che il nostro metodo m3 stia creando un oggetto per la classe "Account", che ne ha due variabile delle istanze int p e int q.
Account { Int p; Int q; }
Ecco il codice per il metodo m3
public void m3(){ Account ref = new Account(); // more code }
L'istruzione new Account() creerà un oggetto di account nell'heap.
La variabile di riferimento “ref” verrà creata in uno stack java.
L'operatore di assegnazione “=" creerà una variabile di riferimento per puntare all'oggetto nell'heap.
Una volta che il metodo ha completato la sua esecuzione, il flusso di controllo tornerà al metodo chiamante. Che in questo caso è il metodo m2.
Lo stack del metodo m3 verrà eliminato.
Poiché la variabile di riferimento non punterà più all'oggetto nell'heap, sarebbe idonea per la garbage collection.
Una volta che il metodo m2 ha completato la sua esecuzione, verrà espulso dallo stack e tutte le sue variabili saranno svuotate e non saranno più disponibili per l'uso.
Lo stesso vale per il metodo m1.
Alla fine, il flusso di controllo tornerà al punto di partenza del programma. Che di solito è il metodo "main".
Cosa succede se Object ha un riferimento come variabile di istanza?
public static void main(String args[]) { A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d; //more code }
In questo caso, la variabile di riferimento “child” verrà creata nell'heap, che a sua volta punterà al suo oggetto, qualcosa di simile al diagramma mostrato di seguito.
In cosa consiste la Garbage Collection Java?
Raccolta rifiuti a Java è un processo mediante il quale i programmi eseguono automaticamente la gestione della memoria. Il Garbage Collector (GC) trova gli oggetti inutilizzati e li elimina per recuperare la memoria. In Java, l'allocazione dinamica della memoria degli oggetti viene ottenuta utilizzando l'operatore new che utilizza una parte della memoria e la memoria rimane allocata finché non ci sono riferimenti per l'uso dell'oggetto.
Quando non ci sono riferimenti a un oggetto, si presume che non sia più necessario e la memoria occupata dall'oggetto può essere recuperata. Non è necessario distruggere un oggetto come Java gestisce automaticamente la deallocazione.
La tecnica che realizza ciò è nota come Raccolta dei rifiuti. I programmi che non deallocano la memoria possono eventualmente bloccarsi quando non c'è più memoria da allocare nel sistema. Si dice che questi programmi abbiano perdite di memoria. Raccolta rifiuti dentro Java avviene automaticamente durante la vita del programma, eliminando la necessità di deallocare memoria ed evitando così perdite di memoria.
Nel linguaggio C, è responsabilità del programmatore deallocare la memoria allocata dinamicamente utilizzando la funzione free(). Questo è dove Java guida alla gestione della memoria.
Nota: Tutti gli oggetti vengono creati nella sezione Heap della memoria. Maggiori informazioni in un tutorial successivo.
Esempio: Per apprendere il meccanismo di raccolta dei rifiuti in Java
Passo 1) Copiare il codice seguente in un editor.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
Passo 2) Salva, compila ed esegui il codice. Come mostrato nel diagramma, vengono creati due oggetti e due variabili di riferimento.
Passo 3) Riga di commento n. 20,21,22. Salva, compila ed esegui il codice.
Passo 4) Come mostrato nel diagramma seguente, due variabili di riferimento puntano allo stesso oggetto.
Passo 5) Decommenta le righe n. 23 e 24. Compila, salva ed esegui il codice
Passo 6) Come mostrato nel diagramma seguente, s2 diventa nullo, ma s3 punta ancora all'oggetto e non è idoneo per la garbage collection Java.
Passo 7) Decommenta le righe n. 25 e 26. Salva, compila ed esegui il codice
Passo 8) A questo punto non ci sono riferimenti che puntano all'oggetto e diventa idoneo per la Garbage Collection. Verrà rimosso dalla memoria e non sarà possibile recuperarlo.
Come eliminare un oggetto in Java?
1) Se vuoi rendere il tuo oggetto idoneo per la Garbage Collection, assegna la sua variabile di riferimento a null.
2) I tipi primitivi non sono oggetti. Non possono essere assegnati nulli.
Sommario:
- Quando viene chiamato un metodo, viene creato un frame in cima allo stack.
- Una volta completata l'esecuzione di un metodo, il flusso di controllo ritorna al metodo chiamante e il corrispondente stack frame viene svuotato.
- Le variabili locali vengono create nello stack
- Le variabili di istanza vengono create nell'heap e fanno parte dell'oggetto a cui appartengono.
- Le variabili di riferimento vengono create nello stack.