2010-09-23 14 views
12

¿Hay alguna forma de limitar fácilmente una aplicación C/C++ a una cantidad específica de memoria (30 mb o menos)? Por ejemplo: si mi aplicación intenta completar la carga de un archivo de 50 mb en memoria, morirá/imprimirá un mensaje y saldrá de/etc.Artificial Limit C/C++ Memory Usage

Es cierto que puedo verificar constantemente el uso de memoria para la aplicación, pero sería un poco más fácil si simplemente muriera con un error si fuera más arriba.

¿Alguna idea?

La plataforma no es un gran problema, compilador de windows/linux/whatever.

+0

¿Por qué no solo verifica el tamaño del archivo? –

Respuesta

9

Lea la página del manual para ulimit en los sistemas Unix. Hay un shell incorporado que puede invocar antes de ejecutar su ejecutable o (en la sección 3 del manual) una llamada API del mismo nombre.

+3

Tenga en cuenta que la API 'ulimit()' está obsoleta. En su lugar, quiere 'setrlimit()'. – bstpierre

+0

@bstpierre: La página man de mi Mac OS 10.5 no menciona nada al respecto (aunque 'setrlimit (2)' también está presente y es posterior a 'ulimit (3)'). ¿Sabes qué estándares hacen el cambio? – dmckee

+1

La página del manual en mi linux box dice: 'CONFORME A SVr4, POSIX.1-2001. POSIX.1-2008 marca ulimit() como obsoleto. Consulte la nota en la [página del manual en línea] (http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13). – bstpierre

4

Anule todas las API malloc y proporcione controladores para nuevo/eliminar, para que pueda reservar mantener el uso de memoria y lanzar excepciones cuando sea necesario.

No estoy seguro si esto es aún más fácil/ahorro de esfuerzo que solo hacer la supervisión de la memoria a través de las API proporcionadas por el sistema operativo.

+0

Haría eso :) (es suficiente para enganchar la API Win32 HeapAlloc()) – ruslik

6

En Windows, no puede establecer una cuota para el uso de memoria de un proceso directamente. Sin embargo, puede crear un objeto de trabajo de Windows, establecer la cuota para el objeto de trabajo y luego asignar el proceso a ese objeto de trabajo.

5

En bash, utilice el ulimit builtin:

bash$ ulimit -v 30000 
bash$ ./my_program 

El -v toma 1K bloques.

Actualización:

Si desea establecer esto desde dentro de su aplicación, utilice setrlimit. Tenga en cuenta que la página man para ulimit(3) dice explícitamente que está obsoleta.

1

Puede limitar el tamaño de la memoria virtual de su proceso utilizando los límites del sistema. Si procesa excede esta cantidad, se matará con una señal (creo que SIGBUS).

Usted puede usar algo como:

#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; 
}; 

y luego usarlo como esa:

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

Esta aplicación parece un poco prolijo pero le permite configurar fácilmente y limpiamente diferentes límites (ver ulimit -a)