Domanda

  

Possibili duplicati:
   Come vengono gestite, implementate, allocate le memorie di heap e stack?
   Stack, Statico e Heap in C ++

In C / C ++ possiamo memorizzare variabili, funzioni, funzioni membro, istanze di una classe su uno stack o un heap.

Come viene implementato? Come viene gestito (alto livello)? Gcc prealloca un pezzo di memoria da utilizzare per lo stack e l'heap e quindi lo distribuisce su richiesta? La memoria originale proviene dalla RAM?

È possibile allocare una funzione sull'heap anziché su uno stack?

             --Clarification--

Chiedo davvero l'implementazione e la gestione delle memorie di heap e stack. Dopo aver letto la domanda di riferimento, non ho trovato nulla che risolva .. grazie per il link

È stato utile?

Soluzione

Penso che alla tua domanda si possa facilmente scrivere almeno alcuni capitoli per il libro sui sistemi operativi. Ti consiglio di leggere Tanenbaum: Modern Operating Systems.

La differenza principale tra heap e stack, quella è per articolo di processo, l'altra per articolo di thread. Inizialmente all'avvio del programma ottiene un minimo heap e alcuni segmenti dello stack. L'heap è cresciuto, lo stack è statico (per ogni thread). Se si scrive una funzione ricorsiva che non termina (ricorsione infinita) si otterrà un overflow dello stack;) Qualsiasi chiamata di funzione ha un frame dello stack sul segmento dello stack, quando la funzione esce, lo stack viene svolto e il frame è libero di essere utilizzato dal prossima funzione. Stack è una struttura lineare continua. Su Linux è possibile configurare la dimensione del segmento dello stack per un processo tramite una variabile di ambiente. Su Windows (almeno con MS Visual C ++) puoi passare un flag linker con le dimensioni del segmento dello stack. Gli overflow dello stack possono anche essere prodotti durante l'allocazione in fase di compilazione di alcuni array di grandi dimensioni:

char test[1000000];

Heap è una storia diversa. Quando un processo si avvia, la dimensione dell'heap è un valore predefinito e può variare dal sistema operativo al sistema operativo o la configurazione utilizzata su quel sistema operativo (ad esempio su Windows, per impostazione predefinita, è di 2 MB, per quanto mi ricordo). Inoltre, se hai bisogno di più heap, per allocare più spazio per le variabili ecc. Crescerà. Se il programma non libera la memoria dell'heap si esaurisce (o spazio dell'heap). Esistono diverse strutture dati per l'implementazione dell'heap, alcune sono derivate da alberi binari, altre no Mucchio di Fibonacci (bosco degli alberi). Puoi leggere alcuni articoli ecc. Su come scrivere un allocatore di memoria. Queste strutture di dati devono essere ottimizzate per trovare il nodo heap quando è necessario disallocare un blocco allocato o aggiungere (trovare un blocco libero) quando è necessario un nuovo spazio heap.

Ogni processo su un sistema operativo a 32 bit ha 4 GB di spazio di indirizzi virtuali. Come puoi immaginare, non può esserci tanta RAM in cui tutti i processi con i loro 4 GB di spazio di indirizzi virtuale si adattano. La memoria del sistema operativo è organizzata in pagine che vengono scambiate in HD quando non sono più necessarie o scadute. Questo è dove il paging viene a giocare. Tutto è mappato su pagine: un processo con lo stack o l'heap in crescita. A causa della struttura dell'heap che cresce dinamicamente, può essere posizionato su più pagine. Questo è il motivo per cui l'accesso all'heap può essere molto costoso, perché se la pagina non è in memoria si verifica un errore di pagina e il sistema operativo deve caricare una pagina dal disco (e questo può essere di gran lunga più lento). Lo stack frame del thread in esecuzione si trova nella cache del processore, che è molto più veloce della RAM.

Sono possibili diversi tipi di heap, potrebbero esserci cumuli molto veloci per piccoli oggetti o cumuli che sono molto efficienti in ambienti multi-thread. Alexandrescu descrive in "Modern C ++ Design" come sviluppare un piccolo allocatore di oggetti e un heap che gestisce piccoli oggetti. Questa implementazione è disponibile nella sua libreria Loki C ++. Alcuni sistemi integrati offrono aree di memoria fisicamente diverse, in cui diversi tipi di heap possono essere implementati in cima. Scrivere un proprio allocatore (heap manager ecc.) È un duro lavoro se vuoi battere un compilatore.

Saluti,
Ovanes

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top