2010-09-23 169 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 )。