Ci sono due limiti di memoria differenti. Il limite di memoria virtuale e il limite di memoria fisica.
Memoria virtuale
La memoria virtuale è limitata dalle dimensioni e dal layout dello spazio degli indirizzi disponibile. Di solito all'inizio sono il codice eseguibile ei dati statici e il passato che fa crescere l'heap, mentre alla fine è l'area riservata dal kernel, prima delle librerie e dello stack condivisi (che nella maggior parte delle piattaforme diminuisce). Ciò consente di aumentare lo spazio libero di heap e stack, mentre le altre aree vengono riconosciute all'avvio del processo e corrette.
La memoria virtuale libera non è inizialmente contrassegnata come utilizzabile, ma è contrassegnata come tale durante l'allocazione. Mentre l'heap può crescere in tutta la memoria disponibile, la maggior parte dei sistemi non accumula automaticamente stack. Il limite predefinito di IIRC per stack è 8MiB su Linux e 1MiB su Windows e può essere modificato su entrambi i sistemi. La memoria virtuale contiene anche file e hardware mappati in memoria.
Uno dei motivi per cui lo stack non può essere auto-cresciuto (arbitrariamente) è che i programmi multi-thread richiedono uno stack separato per ogni thread, quindi alla fine si intrometteranno.
Sulle piattaforme a 32 bit la quantità totale di memoria virtuale è 4GiB, sia Linux che Windows che normalmente riservano l'ultimo 1GiB per il kernel, offrendoti al massimo 3GiB di spazio degli indirizzi. C'è una versione speciale di Linux che non riserva nulla dandoti un 4GiB completo. È utile per il raro caso di database di grandi dimensioni in cui l'ultimo 1GiB salva il giorno, ma per un uso regolare è leggermente più lento a causa del ricarico della tabella di pagine aggiuntivo.
Su piattaforme a 64 bit la memoria virtuale è 64EiB e non devi pensarci.
Memoria fisica
Solitamente la memoria fisica viene allocata dal sistema operativo solo quando il processo deve accedervi. La quantità di memoria fisica utilizzata da un processo è molto sfocata, in quanto parte della memoria è condivisa tra processi (codice, librerie condivise e qualsiasi altro file mappato), i dati dei file vengono caricati in memoria su richiesta e scartati in caso di mancanza di memoria e La memoria "anonima" (quella non supportata dai file) può essere scambiata.
Su Linux, ciò che accade quando si esaurisce la memoria fisica dipende dall'impostazione di sistema vm.overcommit_memory
. L'impostazione predefinita è l'overcommit. Quando chiedi al sistema di allocare memoria, ne fornisce alcuni, ma assegna solo la memoria virtuale. Quando accedi effettivamente alla memoria, cercherà di utilizzare la memoria fisica, scartando i dati che possono essere riletti o scambiati, se necessario. Se trova che non può liberare nulla, rimuoverà semplicemente il processo dall'esistenza (non c'è modo di reagire, perché quella reazione potrebbe richiedere più memoria e ciò porterebbe a un ciclo infinito).
Questo è il modo in cui i processi muoiono su Android (che è anche Linux). La logica è stata migliorata con il processo che logico di rimuovere dall'esistenza in base a ciò che sta facendo il processo e quanti anni ha. I processi Android semplicemente smettono di fare qualsiasi cosa, ma siediti in background e il "killer esaurito" li ucciderà quando ha bisogno di memoria per i nuovi.