15

Is there any way to easily limit a C/C++ application to a specified amount of memory (30 mb or so)? Eg: if my application tries to complete load a 50mb file into memory it will die/print a message and quit/etc.

Admittedly I can just constantly check the memory usage for the application, but it would be a bit easier if it would just die with an error if I went above.

Any ideas?

Platform isn't a big issue, windows/linux/whatever compiler.

Raúl Salinas-Monteagudo
  • 3,412
  • 1
  • 24
  • 22
Paul
  • 2,729
  • 20
  • 26

5 Answers5

10

Read the manual page for ulimit on unix systems. There is a shell builtin you can invoke before launching your executable or (in section 3 of the manual) an API call of the same name.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
  • 4
    Note that the `ulimit()` API is obsolete. You want `setrlimit()` instead. – bstpierre Sep 24 '10 at 17:35
  • @bstpierre: The man page on my Mac OS 10.5 box doesn't mention anything about that (though `setrlimit (2)` is also present and postdates `ulimit (3)`). Do you know what standards make the change? – dmckee --- ex-moderator kitten Sep 24 '10 at 17:45
  • 1
    Man page on my linux box says: `CONFORMING TO SVr4, POSIX.1-2001. POSIX.1-2008 marks ulimit() as obsolete.` See the note on the [online man page](http://www.opengroup.org/onlinepubs/9699919799/functions/ulimit.html#tag_16_630_13). – bstpierre Sep 25 '10 at 00:36
  • 1
    rlimit cannot limit RSS since forever. "See Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED. " – Oleksandr Pryimak Apr 09 '19 at 21:43
  • @AlexandrPriymak Time marches on, it seems. If you have the time an up-to-date post here (or a link to one elsewhere on the site) does more good than just leaving a comment. – dmckee --- ex-moderator kitten Apr 09 '19 at 22:23
7

On Windows, you can't set a quota for memory usage of a process directly. You can, however, create a Windows job object, set the quota for the job object, and then assign the process to that job object.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
5

Override all malloc APIs, and provide handlers for new/delete, so that you can book keep the memory usage and throw exceptions when needed.

Not sure if this is even easier/effort-saving than just do memory monitoring through OS-provided APIs.

Arthur
  • 51
  • 1
5

In bash, use the ulimit builtin:

bash$ ulimit -v 30000
bash$ ./my_program

The -v takes 1K blocks.

Update:

If you want to set this from within your app, use setrlimit. Note that the man page for ulimit(3) explicitly says that it is obsolete.

bstpierre
  • 30,042
  • 15
  • 70
  • 103
3

You can limit the size of the virtual memory of your process using the system limits. If you process exceeds this amount, it will be killed with a signal (SIGBUS I think).

You can use something like:

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

And then use it like that:

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

This implementation seems a bit verbose but it lets you easily and cleanly set different limits (see ulimit -a).

Raúl Salinas-Monteagudo
  • 3,412
  • 1
  • 24
  • 22