【问题标题】:Artificially Limit C/C++ Memory Usage人为限制 C/C++ 内存使用
【发布时间】:2023-04-11 08:24:02
【问题描述】:

有什么方法可以轻松地将 C/C++ 应用程序限制在指定的内存量(30 mb 左右)?例如:如果我的应用程序尝试完成将 50mb 文件加载到内存中,它将死/打印一条消息并退出/等等。

诚然,我可以不断地检查应用程序的内存使用情况,但如果我超过了它会因为错误而死掉会更容易一些。

有什么想法吗?

平台不是什么大问题,windows/linux/whatever 编译器。

【问题讨论】:

  • 为什么不只检查文件的大小?

标签: c++ c memory-management


【解决方案1】:

在 unix 系统上阅读 ulimit 的手册页。有一个内置的 shell,您可以在启动可执行文件之前调用 或(在手册的第 3 节)同名的 API 调用。

【讨论】:

  • 请注意,ulimit() API 已过时。你想要setrlimit()
  • @bstpierre:我的 Mac OS 10.5 盒子上的手册页没有提到任何关于此的内容(尽管 setrlimit (2) 也存在并且更新日期为 ulimit (3))。你知道改变的标准是什么吗?
  • 我的 linux 机器上的手册页说:CONFORMING TO SVr4, POSIX.1-2001. POSIX.1-2008 marks ulimit() as obsolete. 请参阅 online man page 上的注释。
  • rlimit 永远无法限制 RSS。 “请参阅指定进程驻留集的限制(以页为单位)(驻留在 RAM 中的虚拟页数)。此限制仅在 Linux 2.4.x 中有效,x
  • @AlexandrPriymak 时间似乎在前进。如果您有时间在此处发布最新帖子(或指向网站上其他地方的链接),则比仅发表评论更好。
【解决方案2】:

在 Windows 上,您不能直接设置进程的内存使用配额。但是,您可以创建 Windows 作业对象,设置作业对象的配额,然后将进程分配给该作业对象。

【讨论】:

    【解决方案3】:

    覆盖所有 malloc API,并为 new/delete 提供处理程序,以便您可以保留内存使用情况并在需要时抛出异常。

    不确定这是否比仅通过操作系统提供的 API 进行内存监控更容易/省力。

    【讨论】:

    • 我会这样做 :) (挂钩 HeapAlloc() win32 API 就足够了)
    【解决方案4】:

    在 bash 中,使用 ulimit builtin:

    bash$ ulimit -v 30000
    bash$ ./my_program
    

    -v 占用 1K 块。

    更新:

    如果您想在您的应用中进行设置,请使用setrlimit。请注意,ulimit(3) 的手册页明确指出它已过时。

    【讨论】:

      【解决方案5】:

      您可以使用系统限制来限制进程的虚拟内存大小。如果您的进程超过此数量,它将被信号杀死(我认为是 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)。

      【讨论】:

        猜你喜欢
        • 2021-12-23
        • 2018-02-24
        • 2010-12-02
        • 2012-06-27
        • 1970-01-01
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多