Domanda

Vorrei mappare un file in memoria usando la funzione mmap e vorrei sapere se la quantità di memoria virtuale sulla piattaforma corrente è sufficiente per mappare un file enorme. Per un sistema a 32 non posso mappare file di dimensioni superiori a 4 GB.
Sarebbe std::numeric_limits<size_t>::max() dammi la quantità di memoria indirizzabile o c'è qualche altro tipo che dovrei provare (off_t o altro)?

Come Lie Ryan ha sottolineato nel suo commento alla "memoria virtuale" qui è usurpata. La questione, tuttavia tiene: c'è un tipo associato con un puntatore e ha il valore massimo che definisce il limite superiore di quello che si può eventualmente indirizzo sul sistema. Che cosa è questo tipo? È size_t o forse ptrdiff_t?

È stato utile?

Soluzione

size_t è richiesto solo di essere abbastanza grande per memorizzare il più grande singolo oggetto contigui possibile. Che possono non essere la stessa della dimensione dello spazio degli indirizzi (su sistemi con un modello di memoria segmentata, per esempio)

Tuttavia, su piattaforme comuni con uno spazio di memoria piatta, i due sono uguali, e così si può ottenere via con l'utilizzo di size_t in pratica se si conosce la CPU di destinazione.

In ogni caso, questo non davvero dire qualcosa di utile. Certo, una CPU a 32 bit ha uno spazio di memoria di 4GB, e così size_t è un numero intero senza segno a 32 bit. Ma che non dice nulla su quanto è possibile allocare. Una parte dello spazio di memoria viene utilizzata dal sistema operativo. E alcune parti sono già utilizzati da soli la propria applicazione:. Per la mappatura l'eseguibile nella memoria (così come le librerie dinamiche può utilizzare), per lo stack di ciascun thread, memoria allocata sul mucchio e così via

Quindi no, trucchi come prendere le dimensioni del size_t si dice un po 'di spazio degli indirizzi si sta eseguendo in, ma niente di molto usabile. Si può chiedere al sistema operativo la quantità di memoria è in uso da vostro processo e altre metriche, ma ancora una volta, che in realtà non si aiuta molto. E 'possibile per un processo di usare solo un paio di megabyte, ma avere quella distribuito su tante piccole allocazioni che è impossibile trovare un blocco contiguo di memoria più grandi di 100 MB, dicono. E così, su una macchina a 32 bit, con un processo che utilizza quasi alcun ricordo, si sarebbe improbabile per fare questa ripartizione. (E anche se il sistema operativo ha avuto un API WhatIsTheLargestPossibleMemoryAllocationICanMake() magica, che ancora non aiuterebbe voi. Sarebbe dirvi ciò che è necessario da un momento fa . Non si ha garanzia che la risposta sarebbe ancora valida per il momento si è tentato di mappare il file.

Quindi, in realtà, il meglio che puoi fare è cercare per mappare il file, e vedere se fallisce.

Altri suggerimenti

Ciao è possibile utilizzare GlobalMemoryStatusEx e VirtualQueryEx se si codifica in win32

La cosa è, la dimensione di un puntatore vi dice nulla su come molto di quello "spazio di indirizzamento" è in realtà a vostra disposizione, vale a dire possono essere mappati come un unico blocco contiguo.

E 'limitata da:

  • il sistema operativo. Si può scegliere di fare solo un sottoinsieme del teoricamente possibile intervallo di indirizzi a disposizione di voi, perché la memoria mappabili è necessario per scopi di OS-propri (come, ad esempio, rendendo la scheda grafica framebuffer visibile, e, naturalmente, per l'utilizzo da parte del sistema operativo stesso ).
  • limiti configurabili. Su Linux / UNIX, il "ulimit" Comando resp. setrlimit () chiamata di sistema permette di limitare la dimensione massima di spazio di indirizzi di un'applicazione in vari modi, e Windows dispone di opzioni simili attraverso parametri del Registro.
  • la storia dell'applicazione. Se l'applicazione utilizza mappatura della memoria estensivamente, lo spazio di indirizzi può frammentare limitare la dimensione massima di indirizzi virtuali contigui "disponibili".
  • la piattaforma hardware. Alcune CPU hanno spazi di indirizzi con "buchi"; un esempio di che è a 64 bit x86 in cui i puntatori sono valide solo se sono tra 0x0..0x7fffffffffff o 0xffff000000000000 e 0xffffffffffffffff. Cioè avete 2x128TB invece della piena 16EB. Pensate a come 48-bit "firmato" puntatori ...

Infine, non confondere "memoria disponibile" e "spazio di indirizzi a disposizione". C'è una differenza tra il fare una malloc (someBigSize) e una mmap (..., someBigSize, ...) perché il primo potrebbe richiedere la disponibilità di memoria fisica per accogliere la richiesta, mentre il secondo di solito richiede solo la disponibilità di un grande abbastanza libero indirizzo.

Per le piattaforme UNIX, parte della risposta è quella di utilizzare getrlimit (rlimit_as) come questo dà il limite superiore per l'invocazione corrente della vostra applicazione - come detto, l'utente e / o amministratore può configurare questa. Avrete la garanzia che ogni tentativo di mmap aree più grandi di quello fallirà.

Re tua domanda riformulato "limite superiore di quello che si può eventualmente indirizzo sul sistema", è un po 'fuorviante; la sua architettura hardware specifico. Ci sono 64 bit architetture là fuori (x64, SPARC), il cui MMU permette felicemente (uintptr_t) (- 1) come indirizzo valido, cioè è possibile mappare qualcosa nella ultima pagina di uno spazio di indirizzamento a 64 bit. Se il sistema operativo consente a un'applicazione di farlo o no è ancora una volta una questione completamente diversa ...

Per applicazioni utente, l ' "alta marchio" non è (sempre) fissato a priori. E 'sintonizzabile sulla esempio Solaris o Linux. Ecco dove getrlimit (rlimit_as) entra in gioco.

Si noti che ancora una volta, dalla specifica, non ci sarebbe nulla per impedire un (strano) la progettazione del sistema operativo da scegliere per esempio mettendo stack applicativi e mucchi indirizzi "basse" mettendo codice a indirizzi "alte", su una piattaforma con fori spazio di indirizzi. Avreste bisogno di puntatori a 64 bit pieni lì, non può fare loro alcun più piccolo, ma ci potrebbe essere un numero arbitrario di gamme "inaccessibili / non valido", che non vengono messi a disposizione per la vostra applicazione.

Si può provare sizeof(int*). Questo vi darà la lunghezza (in bytes) di un puntatore sulla piattaforma di destinazione. Così, si può scoprire quanto è grande lo spazio indirizzabile è.

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