Allocazione della memoria stack e heap

Allocazione della memoria stack e heap

La memoria in un programma C/C++/Java può essere allocata su uno stack o su un heap.
Prerequisito: Layout della memoria del programma C .


Allocazione dello stack: L'allocazione avviene su blocchi di memoria contigui. La chiamiamo allocazione di memoria dello stack perché l'allocazione avviene nello stack di chiamate di funzione. La dimensione della memoria da allocare è nota al compilatore e ogni volta che viene chiamata una funzione, le sue variabili ricevono memoria allocata nello stack. E ogni volta che la chiamata della funzione termina, la memoria per le variabili viene deallocata. Tutto questo avviene utilizzando alcune routine predefinite nel compilatore. Un programmatore non deve preoccuparsi dell'allocazione e della deallocazione della memoria delle variabili dello stack. Questo tipo di allocazione di memoria è nota anche come allocazione di memoria temporanea perché non appena il metodo termina l'esecuzione, tutti i dati appartenenti a quel metodo vengono automaticamente eliminati dallo stack. Ciò significa che qualsiasi valore archiviato nello schema di memoria dello stack è accessibile finché il metodo non ha completato la sua esecuzione ed è attualmente in uno stato di esecuzione.

Punti chiave:

  • È uno schema di allocazione temporanea della memoria in cui i membri dati sono accessibili solo se il metodo () che li conteneva è attualmente in esecuzione.
  • Alloca o dealloca la memoria automaticamente non appena il metodo corrispondente completa la sua esecuzione.
  • Riceviamo l'errore Java corrispondente. lang. Errore StackOverFlow di JVM , Se la memoria dello stack è completamente piena.
  • L'allocazione della memoria nello stack è considerata più sicura rispetto all'allocazione della memoria nell'heap perché è possibile accedere ai dati archiviati solo dal thread proprietario.
  • L'allocazione e la deallocazione della memoria sono più veloci rispetto all'allocazione della memoria heap.
  • La memoria stack ha meno spazio di archiviazione rispetto alla memoria heap.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; } 


Allocazione dell'heap: La memoria viene allocata durante l'esecuzione delle istruzioni scritte dai programmatori. Tieni presente che l'heap dei nomi non ha nulla a che fare con il file perdita di memoria può accadere nel programma.

L'allocazione della memoria Heap è ulteriormente suddivisa in tre categorie: - Queste tre categorie ci aiutano a dare priorità ai dati (oggetti) da archiviare nella memoria Heap o nel Raccolta dei rifiuti .

  • Generazione giovane – È la parte della memoria in cui vengono creati tutti i nuovi dati (oggetti) per allocare lo spazio e ogni volta che questa memoria è completamente riempita, il resto dei dati viene archiviato nella Garbage collection.
  • Generazione vecchia o di ruolo – Questa è la parte della memoria heap che contiene gli oggetti dati più vecchi che non sono utilizzati frequentemente o non vengono utilizzati affatto.
  • Generazione Permanente – Questa è la porzione di memoria heap che contiene i metadati della JVM per le classi runtime e i metodi dell'applicazione.

Punti chiave:

  • Riceviamo il messaggio di errore corrispondente se lo spazio heap è completamente pieno, Giava. lang.OutOfMemoryError di JVM.
  • Questo schema di allocazione della memoria è diverso dall'allocazione dello spazio nello stack, qui non viene fornita alcuna funzionalità di deallocazione automatica. Dobbiamo utilizzare un Garbage Collector per rimuovere i vecchi oggetti inutilizzati per utilizzare la memoria in modo efficiente.
  • Il tempo di elaborazione (tempo di accesso) di questa memoria è piuttosto lento rispetto alla memoria Stack.
  • Inoltre, la memoria heap non è sicura per i thread come la memoria stack perché i dati archiviati nella memoria heap sono visibili a tutti i thread.
  • La dimensione della memoria Heap è molto maggiore rispetto alla memoria Stack.
  • La memoria heap è accessibile o esiste finché viene eseguita l'intera applicazione (o programma Java).
CPP
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; } 

Esempio misto di entrambi i tipi di allocazione di memoria Heap e Stack in Java:

C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; } 
Giava
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } } 
Pitone
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main() 
Javascript
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console 

Di seguito sono riportate le conclusioni a cui giungeremo dopo aver analizzato l’esempio sopra:

  • Quando iniziamo l'esecuzione del programma have, tutte le classi di runtime vengono archiviate nello spazio di memoria Heap.
  • Poi troviamo nella riga successiva il metodo main() che viene memorizzato nello stack insieme a tutte le sue primitive(o locali) e anche la variabile di riferimento Emp di tipo Emp_detail verrà memorizzata nello Stack e indicherà l'oggetto corrispondente memorizzati nella memoria Heap.
  • Quindi la riga successiva chiamerà il costruttore parametrizzato Emp(int, String) da main( ) e allocherà anche all'inizio dello stesso blocco di memoria dello stack. Questo memorizzerà:
    • Il riferimento all'oggetto richiamato della memoria dello stack.
    • Il valore primitivo( La variabile di riferimento dell'argomento String emp_name punterà alla stringa effettiva dal pool di stringhe nella memoria heap.
  • Quindi il metodo main chiamerà nuovamente il metodo statico Emp_detail(), per il quale l'allocazione verrà effettuata nel blocco di memoria dello stack sopra il blocco di memoria precedente.
  • La variabile di riferimento dell'argomento String emp_name punterà alla stringa effettiva dal pool di stringhe nella memoria heap.
  • Pertanto, per l'oggetto appena creato Emp di tipo Emp_detail e tutte le variabili di istanza verranno archiviate nella memoria heap.
  • La variabile di riferimento dell'argomento String emp_name punterà alla stringa effettiva dal pool di stringhe nella memoria heap.

  • Rappresentazione pittorica come mostrato nella Figura.1 di seguito:

    La variabile di riferimento dell'argomento String emp_name punterà alla stringa effettiva dal pool di stringhe nella memoria heap.
  • Fig. 1

    Differenze chiave tra allocazioni stack e heap

    1. In uno stack, l'allocazione e la deallocazione vengono eseguite automaticamente dal compilatore mentre, nell'heap, deve essere eseguita manualmente dal programmatore.
    2. La gestione dell'Heap Frame è più costosa rispetto alla gestione dello Stack Frame.
    3. È più probabile che il problema della carenza di memoria si verifichi nello stack mentre il problema principale nella memoria heap è la frammentazione.
    4. L'accesso allo stack frame è più semplice rispetto all'heap frame poiché lo stack ha una piccola regione di memoria ed è compatibile con la cache, ma nel caso di heap frame che sono dispersi in tutta la memoria, ciò causa più errori di cache.
    5. Uno stack non è flessibile, la dimensione della memoria allocata non può essere modificata mentre un heap è flessibile e la memoria allocata può essere modificata.
    6. L'accesso al tempo di heap takes è più di uno stack.

    Grafico comparativo

    Parametro PILA MUCCHIO
    Di base La memoria viene allocata in un blocco contiguo. La memoria viene allocata in qualsiasi ordine casuale.
    Allocazione e deallocazione Automatico tramite istruzioni del compilatore. Manuale del programmatore.
    Costo Meno Di più
    Implementazione Facile Difficile
    Orario di accesso Più veloce Più lentamente
    Problema principale Carenza di memoria Frammentazione della memoria
    Località di riferimento Eccellente Adeguato
    Sicurezza Thread-safe, i dati archiviati sono accessibili solo al proprietario Non thread-safe, i dati archiviati sono visibili a tutti i thread
    Flessibilità Taglia unica Il ridimensionamento è possibile
    Struttura del tipo di dati Lineare Gerarchico
    Preferito In un array è preferibile l'allocazione statica della memoria. Nell'elenco collegato è preferibile l'allocazione della memoria heap.
    Misurare Piccola memoria heap. Più grande della memoria dello stack.