Segmentazione della memoria: stack, heap, ecc.?

0

Quindi la segmentazione della memoria può essere eseguita con o senza impaginazione. Sento sempre persone che parlano di stack e heap quando discutono di qualcosa relativo alla memoria in C ++. Tuttavia, ciò che non ottengo è che se la memoria del programma (il suo spazio di indirizzamento virtuale) è segmentata usando le pagine, non verrà divisa in stack, heap, ecc., Giusto? Ma piuttosto è diviso in pagine senza nomi - in tal caso (supponendo che la mia comprensione della segmentazione sia corretta), puoi ancora parlare dello stack e dell'heap?

Inoltre, se lo spazio degli indirizzi virtuali è diviso in pagine, da dove provengono i segmenti stack, heap, data, ecc.?

    
posta asd 10.02.2018 - 12:58
fonte

3 risposte

2

Lo stack e l'heap in C / C ++ descrivono diversi meccanismi di allocazione della memoria. Possono anche essere chiamati "archiviazione automatica" e "negozio gratuito". Se si assegnano i dati sullo store / heap liberi, si è responsabili della gestione della durata (chiamando delete o free() ). Questo è in gran parte non correlato alle pagine di memoria.

Le pagine di memoria sono un blocco di indirizzi virtuali. Lo spazio di indirizzamento virtuale di un processo viene creato dal sistema operativo mappando le pagine nello spazio degli indirizzi.

Un processo utilizza diverse aree dello spazio degli indirizzi in modo diverso. Un'area sarà la pila. Altre aree manterranno il contenuto di file e librerie eseguibili. Questi file possono avere segmenti diversi, ad es. per codice eseguibile, per costanti e spazio per variabili.

Qui ho richiamato le mappature dello spazio degli indirizzi di un interprete Perl usando pmap:

0000000000400000   1776K r-x-- perl
00000000007bb000      4K r---- perl
00000000007bc000     12K rw--- perl
00000000007bf000      4K rw---   [ anon ]
0000000001eff000   1192K rw---   [ anon ]
00007f00184b7000   4464K r---- locale-archive
00007f0018913000   1792K r-x-- libc-2.23.so
00007f0018ad3000   2048K ----- libc-2.23.so
00007f0018cd3000     16K r---- libc-2.23.so
00007f0018cd7000      8K rw--- libc-2.23.so
00007f0018cd9000     16K rw---   [ anon ]
00007f0018cdd000     36K r-x-- libcrypt-2.23.so
00007f0018ce6000   2044K ----- libcrypt-2.23.so
00007f0018ee5000      4K r---- libcrypt-2.23.so
00007f0018ee6000      4K rw--- libcrypt-2.23.so
00007f0018ee7000    184K rw---   [ anon ]
00007f0018f15000   1056K r-x-- libm-2.23.so
00007f001901d000   2044K ----- libm-2.23.so
00007f001921c000      4K r---- libm-2.23.so
00007f001921d000      4K rw--- libm-2.23.so
00007f001921e000     12K r-x-- libdl-2.23.so
00007f0019221000   2044K ----- libdl-2.23.so
00007f0019420000      4K r---- libdl-2.23.so
00007f0019421000      4K rw--- libdl-2.23.so
00007f0019422000     96K r-x-- libpthread-2.23.so
00007f001943a000   2044K ----- libpthread-2.23.so
00007f0019639000      4K r---- libpthread-2.23.so
00007f001963a000      4K rw--- libpthread-2.23.so
00007f001963b000     16K rw---   [ anon ]
00007f001963f000    152K r-x-- ld-2.23.so
00007f0019839000     20K rw---   [ anon ]
00007f0019864000      4K r---- ld-2.23.so
00007f0019865000      4K rw--- ld-2.23.so
00007f0019866000      4K rw---   [ anon ]
00007ffc0cd0a000    136K rw---   [ stack ]
00007ffc0cd4e000     12K r----   [ anon ]
00007ffc0cd51000      8K r-x--   [ anon ]
ffffffffff600000      4K r-x--   [ anon ]
 total            21284K

Si noti che la dimensione più piccola è 4K, cioè la dimensione della pagina sul mio sistema.

Possiamo vedere nella colonna più a destra quali file (eseguibili o librerie) sono stati mappati nello spazio degli indirizzi a cui è stato eseguito l'offset. Esistono anche un paio di regioni speciali, come [stack] . Alcune delle regioni anonime possono essere utilizzate come archivio / heap gratuito. Ci possono essere spazi tra gli intervalli mappati dello spazio degli indirizzi. Provare ad accedere alla memoria in un intervallo non associato causerà un segfault.

Ciascuna di queste regioni è composta da una o più pagine. Questo è importante, perché le pagine possono avere protezioni di accesso: i file eseguibili e le librerie forniscono pagine eseguibili per codice, pagine di sola lettura per le costanti e pagine di lettura-scrittura per variabili. Questo è un meccanismo di sicurezza per evitare l'esecuzione di dati arbitrari (anche se questo non è molto importante per un interprete ). Le pagine per l'heap e lo stack saranno leggibili e scrivibili, ma non eseguibili.

Un intervallo di indirizzi può essere mappato, ma la pagina per quell'indirizzo potrebbe non esistere al momento. L'utilizzo di tale indirizzo attiverà un errore di pagina. Il sistema operativo può intercettare l'errore di pagina e aggiungere la pagina. Ad esempio, non tutte le pagine del 136 K per lo stack possono esistere all'avvio del processo. Invece, le pagine vengono aggiunte su richiesta. Oppure, una pagina potrebbe essere stata scambiata su disco. Un errore di pagina causerà il caricamento di quella pagina nella memoria fisica.

    
risposta data 10.02.2018 - 13:51
fonte
4

Il concetto di pagine risiede a un livello inferiore rispetto al concetto di heap e stack. Quindi sì, puoi ancora parlare della separazione di heap e stack. Sono costruiti in cima alle pagine.

I segmenti di memoria possono puntare alla memoria fisica o alla memoria virtuale basata su pagine. I file oggetto possono anche essere suddivisi in segmenti.

Come utente di funzioni di alto livello come malloc() o new operatore non noterai in alcun modo btw. A meno che tu non acceda a indirizzi al di fuori degli intervalli assegnati o esaurisca lo spazio disponibile.

    
risposta data 10.02.2018 - 13:41
fonte
1

Il testo (binario), i dati, l'heap e lo stack sono divisioni logiche (segmenti) della memoria del programma. Le pagine sono le divisioni hardware. L'hardware che esegue il paging gestisce anche la traduzione da un indirizzo logico a un indirizzo fisico.

Esistono due modelli di memoria: il modello logico dei segmenti e il modello fisico delle pagine. E l'hardware esegue automaticamente la traduzione tra loro.

PS: le pagine non devono essere assegnate consecutivamente o in qualsiasi ordine. La prima pagina potrebbe provenire da una memoria insufficiente, la successiva dall'alto e la successiva da qualche parte nel mezzo. Questo è uno dei principali vantaggi del paging: qualsiasi pagina libera può essere assegnata al successivo indirizzo logico.

    
risposta data 10.02.2018 - 13:32
fonte

Leggi altre domande sui tag