2010-09-23 35 views
12

有沒有什麼辦法可以輕鬆地將C/C++應用程序限制到指定的內存量(30 MB左右)?例如:如果我的應用程序試圖完成將50mb文件加載到內存中,它將會死/打印一條消息並退出/ etc。人工限制C/C++內存使用

不可否認,我可以不斷檢查應用程序的內存使用情況,但如果我上面去了,它會因爲錯誤而死亡,這會更容易一些。

任何想法?

平臺不是一個大問題,windows/linux /無論編譯器。

+0

爲什麼不只是檢查文件的大小? – 2010-09-23 01:46:06

回答

9

請閱讀關於unix系統上的ulimit的手冊頁。有一個shell內建可以調用,然後啓動您的可執行文件或(在手冊的第3節中)調用同名的API調用。

+3

請注意,'ulimit()'API已過時。你需要'setr​​limit()'。 – bstpierre 2010-09-24 17:35:51

+0

@bstpierre:我的Mac OS 10.5盒子的man頁面沒有提到任何關於這個的東西(儘管'setr​​limit(2)'也存在並且後置了'ulimit(3)')。你知道什麼標準可以改變嗎? – dmckee 2010-09-24 17:45:33

+1

我的Linux機器上的手冊頁說:「符合SVr4,POSIX.1-2001。 POSIX.1-2008將ulimit()標記爲廢棄。請參見[在線手冊頁](http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13)上的註釋。 – bstpierre 2010-09-25 00:36:44

4

覆蓋所有malloc API,併爲new/delete提供處理程序,以便您可以預訂時保留內存使用情況並在需要時引發異常。

不知道這是否比通過OS提供的API進行內存監視更簡單/省力。

+0

我會這樣做:)(它足以鉤住HeapAlloc()win32 API) – ruslik 2010-09-23 03:36:43

6

在Windows上,您無法直接設置進程內存使用的配額。但是,您可以創建Windows作業對象,設置作業對象的配額,然後將該過程分配給該作業對象。

5

在bash,使用ulimit builtin

bash$ ulimit -v 30000 
bash$ ./my_program 

的-v需要1K塊。

更新:

如果你想從你的應用程序中設置此,使用setrlimit。請注意,ulimit(3)的手冊頁明確指出它已過時。

1

您可以使用系統限制來限制進程虛擬內存的大小。如果你的流程超過這個數量,它會被一個信號殺死(我認爲是SIGBUS)。

您可以使用類似:

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

,然後用它這樣的:

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

這個實現似乎有點冗長,但它可以讓你輕鬆乾淨地設置不同的限制(見ulimit -a )。