2013-02-21 17 views
6

E 'possibile ottenere la memoria disponibile rimanente su un sistema (x86, x64, PowerPC/Windows, Linux o MacOS) nello standard C++ 11 senza arrestarsi in modo anomalo?Ottieni la memoria disponibile rimanente in C++ 11 standard?

Un modo semplice sarebbe quello di provare allocare le matrici molto grandi a partire da troppo grandi dimensioni, intercettare le eccezioni ogni volta fallisce e ridurre le dimensioni fino a quando viene lanciata non fa eccezione. Ma forse c'è un metodo più efficiente/intelligente ...

MODIFICA 1: In effetti non ho bisogno della quantità esatta di memoria. Mi piacerebbe sapere approssimativamente (barra di errore di 100 MB) quanto il mio codice potrebbe utilizzare quando lo avvio.

EDIT 2: Cosa ne pensi di questo codice? È sicuro eseguirlo all'inizio del mio programma o potrebbe danneggiare la memoria?

#include <iostream> 
#include <array> 
#include <list> 
#include <initializer_list> 
#include <stdexcept> 

int main(int argc, char* argv[]) 
{ 
    static const long long int megabyte = 1024*1024; 
    std::array<char, megabyte> content({{'a'}}); 
    std::list<decltype(content)> list1; 
    std::list<decltype(content)> list2; 
    const long long int n1 = list1.max_size(); 
    const long long int n2 = list2.max_size(); 
    long long int i1 = 0; 
    long long int i2 = 0; 
    long long int result = 0; 
    for (i1 = 0; i1 < n1; ++i1) { 
     try { 
      list1.push_back(content); 
     } 
     catch (const std::exception&) { 
      break; 
     } 
    } 
    for (i2 = 0; i2 < n2; ++i2) { 
     try { 
      list2.push_back(content); 
     } 
     catch (const std::exception&) { 
      break; 
     } 
    } 
    list1.clear(); 
    list2.clear(); 
    result = (i1+i2)*sizeof(content); 
    std::cout<<"Memory available for program execution = "<<result/megabyte<<" MB"<<std::endl; 
    return 0; 
} 
+0

Siamo spiacenti, questa volta il "no" tra i due possibili risultati di "forse" è uscito. –

+0

Questo è altamente dipendente dalla piattaforma e non è trattato nello standard. –

+0

Non esiste un modo "standard" per farlo. Anche il metodo che descrivi potrebbe non restituire risultati validi. È necessario utilizzare funzionalità specifiche della piattaforma. –

risposta

8

Questo è altamente dipendente dal sistema operativo/piattaforma. L'approccio che suggerisci non ha nemmeno bisogno di funzionare nella vita reale. In alcune piattaforme del sistema operativo ti darà tutte le vostre richieste di memoria, ma non davvero dare la memoria fino a quando si usa che, a quel punto si ottiene un SEGFAULT ...

Lo standard non non ha tutto ciò che riguarda a questa.

+0

Segfault non sarebbe un risultato probabile. Su Mac OS X, il processo verrebbe sospeso. In ogni caso, la macchina di solito inizia a "thrash" per prima cosa. – Potatoswatter

+0

@Potatoswatter: prova una finestra Linux, rimuovi il file di scambio, assegna un array dinamico abbastanza grande e percorrilo toccando ogni, diciamo 4096 ° byte per toccare tutte le pagine di memoria. Almeno in passato sarebbe morto con un SEGFAULT –

+0

@ DavidRodríguez-dribeas - Questo è Linux, OSX è diverso. È "altamente dipendente", come hai detto tu. Il punto chiave è che su alcuni sistemi si può allocare con successo molta più memoria di quella disponibile anche nella memoria virtuale, dove "successo" significa nessun lancio da nuovo, o un puntatore non nullo da malloc. Il problema potrebbe non manifestarsi fino a dopo che la quantità di memoria fasulla di memoria è stata allocata "correttamente". –

2

Mi sembra che la risposta sia no, non è possibile farlo in C++ standard.

Quello che si potrebbe fare invece è discusso in How to get available memory C++/g++? e il contenuto collegato lì. Queste sono tutte cose specifiche della piattaforma. Non è standard ma almeno ti aiuta a risolvere il problema che stai affrontando.

1

Come altri hanno già detto, il problema è difficile da definire con precisione, tanto meno da risolvere. La memoria virtuale sull'hard disk conta come "disponibile"? Che dire se il sistema implementa un prompt per eliminare i file per ottenere più spazio sul disco rigido, nel frattempo sospendendo il programma? (Questo è esattamente ciò che accade su OS X.)

Il sistema implementa probabilmente una gerarchia di memoria che diventa più lenta man mano che si utilizza di più. Potresti provare a rilevare il limite di prestazioni tra RAM e disco allocando e inizializzando blocchi di memoria mentre utilizzi la funzione di interruzione C alarm o clock o localtime/mktime o le funzioni di clock di C++ 11. Il tempo di wall-clock dovrebbe apparire più veloce mentre la macchina rallenta sotto lo stress di ottenere memoria da risorse meno efficienti. (Ma ciò presuppone che non sia sottolineato da nient'altro come un altro processo.) Si vorrebbe dire all'utente cosa sta tentando il programma e salvare i risultati in un file di configurazione modificabile.

1

Si consiglia di utilizzare invece una quantità massima di memoria configurabile. Dal momento che alcune piattaforme sovraccaricano la memoria, non è facile stabilire la quantità di memoria a cui si avrà effettivamente accesso. Inoltre, non è educato supporre di avere accesso esclusivo al 100% della memoria disponibile, molti sistemi avranno altri programmi in esecuzione.

Problemi correlati