2010-09-23 16 views
12

Esiste un modo per limitare facilmente un'applicazione C/C++ a una quantità di memoria specifica (30 MB circa)? Ad esempio: se la mia applicazione tenta di completare il caricamento di un file 50mb in memoria, muoia/stampa un messaggio e chiude/etc.Limita artificialmente utilizzo memoria C/C++

Devo ammettere che è possibile controllare costantemente l'utilizzo della memoria per l'applicazione, ma sarebbe un po 'più semplice se dovesse morire con un errore se avessi passato sopra.

Qualche idea?

La piattaforma non è un grosso problema, windows/linux/qualsiasi compilatore.

+0

Perché non basta controllare la dimensione del file? –

risposta

9

Leggere la pagina di manuale per ulimit su sistemi unix. C'è una shell integrata che puoi invocare prima del avviando il tuo eseguibile o (nella sezione 3 del manuale) una chiamata API con lo stesso nome.

+3

Nota che l'API 'ulimit()' è obsoleta. Vuoi invece 'setrlimit()'. – bstpierre

+0

@bstpierre: La pagina man sul mio Mac OS 10.5 box non menziona nulla a riguardo (anche se 'setrlimit (2)' è anche presente e postdates 'ulimit (3)'). Sai quali standard fanno il cambiamento? – dmckee

+1

La pagina man sulla mia finestra linux dice: 'CONFORME A SVr4, POSIX.1-2001. POSIX.1-2008 segna ulimit() come obsoleto. Vedere la nota sulla [man man online] (http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13). – bstpierre

4

Sovrascrive tutte le API di malloc e fornisce gestori per nuovi/cancella, in modo che sia possibile prenotare mantenere l'utilizzo della memoria e generare eccezioni quando necessario.

Non è sicuro se questo sia ancora più semplice/risparmio di energia rispetto al semplice monitoraggio della memoria tramite le API fornite dal sistema operativo.

+0

Lo farei :) (è sufficiente collegare l'API win32 HeapAlloc()) – ruslik

6

Su Windows, non è possibile impostare una quota per l'utilizzo della memoria di un processo direttamente. Tuttavia, è possibile creare un oggetto lavoro Windows, impostare la quota per l'oggetto lavoro e quindi assegnare il processo a tale oggetto lavoro.

5

In bash, utilizzare il ulimit builtin:

bash$ ulimit -v 30000 
bash$ ./my_program 

Il -v prende 1K blocchi.

Aggiornamento:

Se si desidera impostare questo da dentro la vostra applicazione, utilizzare setrlimit. Si noti che la pagina man per ulimit(3) dice esplicitamente che è obsoleto.

1

È possibile limitare la dimensione della memoria virtuale del processo utilizzando i limiti del sistema. Se il processo supera questa quantità, verrà ucciso con un segnale (penso SIGBUS).

Si può usare qualcosa di simile a:

#include <sys/resource.h> 
#include <iostream> 

using namespace std; 

class RLimit { 
public: 
    RLimit(int cmd) : mCmd(cmd) { 
    } 

    void set(rlim_t value) { 
     clog << "Setting " << mCmd << " to " << value << endl; 
     struct rlimit rlim; 
     rlim.rlim_cur = value; 
     rlim.rlim_max = value; 
     int ret = setrlimit(mCmd, &rlim); 
     if (ret) { 
      clog << "Error setting rlimit" << endl; 
     } 
    } 

    rlim_t getCurrent() { 
     struct rlimit rlim = {0, 0}; 
     if (getrlimit(mCmd, &rlim)) { 
      clog << "Error in getrlimit" << endl; 
      return 0; 
     } 
     return rlim.rlim_cur; 
    } 
    rlim_t getMax() { 
     struct rlimit rlim = {0, 0}; 
     if (getrlimit(mCmd, &rlim)) { 
      clog << "Error in getrlimit" << endl; 
      return 0; 
     } 
     return rlim.rlim_max; 
    } 

private: 
    int mCmd; 
}; 

e quindi utilizzarlo come quella:

RLimit dataLimit(RLIMIT_DATA); 
dataLimit.set(128 * 1024); // in kB 
clog << "soft: " << dataLimit.getCurrent() << " hard: " << dataLimit.getMax() << endl; 

Questa implementazione sembra un po 'prolisso, ma li lascia facilmente e in modo pulito impostare limiti diversi (vedi ulimit -a).