2010-09-23 11 views
12

Czy istnieje sposób na łatwe ograniczenie aplikacji C/C++ do określonej ilości pamięci (około 30 MB)? Np .: jeśli moja aplikacja próbuje ukończyć załadowanie pliku 50mb do pamięci, umrze/wydrukuje komunikat i zakończy działanie/etc.Ograniczenie sztucznej pamięci C/C++

Wprawdzie mogę po prostu stale sprawdzać zużycie pamięci dla aplikacji, ale byłoby to trochę łatwiejsze, gdyby po prostu umarł z błędem, gdybym podszedł powyżej.

Wszelkie pomysły?

Platforma nie jest dużym problemem, Windows/Linux/jakiegokolwiek kompilatora.

+0

Dlaczego nie wystarczy sprawdzić rozmiar pliku? –

Odpowiedz

9

Przeczytaj stronę podręcznika dla systemów ulimit na systemach unix. Jest wbudowana powłoka, w której możesz wywołać przed, uruchamiając twój plik wykonywalny lub (w sekcji 3 instrukcji) wywołanie API o tej samej nazwie.

+3

Zauważ, że API 'ulimit()' jest przestarzałe. Zamiast tego potrzebujesz 'setrlimit()'. – bstpierre

+0

@bstpierre: Strona man na moim Mac OS 10.5 nie wspomina nic o tym (chociaż 'setrlimit (2)' jest również obecny i postdates 'ulimit (3)'). Czy wiesz, jakie standardy wprowadzają zmiany? – dmckee

+1

Strona podręcznika na moim komputerze linux mówi: 'ZGODNE Z SVr4, POSIX.1-2001. POSIX.1-2008 oznacza, że ​​ulimit() jest przestarzały. Patrz uwaga na stronie [online man page] (http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13). – bstpierre

4

Zastępuje wszystkie API malloc i udostępnia moduły obsługi nowego/usuwanego, dzięki czemu można zarezerwować przechowywanie pamięci i generowanie wyjątków w razie potrzeby.

Nie jestem pewien, czy jest to jeszcze łatwiejsze/oszczędza wysiłek, niż tylko monitorowanie pamięci za pośrednictwem interfejsów API dostarczanych przez system operacyjny.

+0

Zrobiłbym to :) (wystarczy zahaczyć API WinA HeapAlloc()) – ruslik

6

W systemie Windows nie można ustawić limitu użycia pamięci bezpośrednio w procesie. Można jednak utworzyć obiekt zadania Windows, ustawić przydział dla obiektu zadania, a następnie przypisać proces do tego obiektu zadania.

5

W bash, użyj ulimit builtin:

bash$ ulimit -v 30000 
bash$ ./my_program 

-v trwa 1K bloków.

Aktualizacja:

Jeśli chcesz ustawić to z poziomu aplikacji, należy użyć setrlimit. Zwróć uwagę, że strona podręcznika dla ulimit(3) mówi wprost, że jest przestarzała.

1

Można ograniczyć wielkość pamięci wirtualnej procesu przy użyciu limitów systemowych. Jeśli przetwarzasz więcej niż ta kwota, zostanie zabity z sygnałem (myślę, że SIGBUS).

Można użyć coś takiego:

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

a następnie używać go tak:

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

Implementacja ta wydaje się nieco rozwlekły, ale pozwala łatwo i czysto ustawić różne limity (patrz ulimit -a).

Powiązane problemy