[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Limiting the amount of memory an application can allocate



Hello Everyone,

I'm going to need your help on this one.  Basically,
I'm trying to limit the amount of memory than an
application can allocate so that a single user
application does not hog up all the memory and bring
down the system.

As a test, I've limited user "rig" to 10 Megabytes of
physical memory in "limits.conf".

$ grep rss /etc/security/limits.conf
rig soft rss 10000
rig hard rss 10000

$ id
uid=502(rig) gid=502(rig) groups=502(rig)

$ ulimit -a | grep "max memory"
max memory size         (kbytes, -m) 10000

To test if this works, I've put together this basic
program which allocates the amount of memory that is
passed to it as the first argument.

$ cat allocmem.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

char *progname = NULL;

void show_limit()
{
        struct rlimit rlim;

        if (getrlimit( RLIMIT_DATA, &rlim) == -1)
        {
                perror("getrlimit");
                exit(1);
        }

        printf("RLIMIT_DATA: rlim_cur = %d, rlim_max =
%d\n", rlim.rlim_cur, rlim.rlim_max);
}

long
get_max_memory()
{
        FILE *fp;

        char buf[BUFSIZ];

        char *cmd = "ulimit -m";

        if ((fp = popen( cmd, "r")) == NULL)
        {
                perror("popen");
                exit(1);
        }

        if ((fgets( buf, sizeof(buf), fp)) == NULL)
        {
                perror("fgets");
                exit(1);
        }

        pclose(fp);

        return ( atol(buf) * 1024 );
}

long
get_free_mem()
{
        FILE *fp;

        char buf[BUFSIZ];

        char *cmd = "grep MemFree /proc/meminfo  | awk
'{ print $2 }'";

        if ((fp = popen( cmd, "r")) == NULL)
        {
                perror("popen");
                exit(1);
        }

        if ((fgets( buf, sizeof(buf), fp)) == NULL)
        {
                perror("fgets");
                exit(1);
        }

        pclose(fp);

        return (atol(buf) * 1024);
}

long
get_rss()
{
        FILE *fp;

        char buf[BUFSIZ];
        char cmd[BUFSIZ];

        sprintf( cmd,
                "ps awux | grep %s | grep -v grep |
awk '{ print $6 }'",
                progname);

        if ((fp = popen( cmd, "r")) == NULL)
        {
                perror("popen");
                exit(1);
        }

        if ((fgets( buf, sizeof(buf), fp)) == NULL)
        {
                perror("fgets");
                exit(1);
        }

        pclose(fp);

        return (atol(buf) * 1024);
}

main( int argc, char *argv[])
{
        char *s;
        size_t n;
        long mem_free1, mem_free2;

        if (argc != 2)
        {
                printf("usage: %s <size>\n", argv[0]);
                exit(1);
        }

        progname = argv[0];

        n = atol(argv[1]);

        show_limit();

        mem_free1  = get_free_mem();

        if ((s = (char*) malloc( n )) == NULL)
        {
                perror("malloc");
                exit(1);
        }

        memset( s, '\0', n);

        mem_free2  = get_free_mem();

        printf("max memory       = %ld\n",
get_max_memory());
        printf("memory requested = %ld\n", n);
        printf("memory used      = %ld\n", mem_free1 -
mem_free2);
        printf("rss              = %ld\n", get_rss());

        exit(0);
}

$ cc -o allocmem allocmem.c

As you can see when I run the program, RLIMIT_DATA is
unlimited.

$ /hptc_cluster/tmp/rig/allocmem 1000000000
RLIMIT_DATA: rlim_cur = -1, rlim_max = -1
max memory       = 10240000
memory requested = 1000000000
memory used      = 1001914368
rss              = 1000431616

In the output above, "max memory" is the value of
"ulimit -a" times 1024 to convert from kilobytes to
bytes, "memory requested" is what you pass into the
program as the first argument, "memory used" is the
difference in free memory before and after the
"malloc()", and "rss" is the RSS value from the "ps"
command.

If my crude method for estimating the physical memory
used is reasonably correct, you can see that 1 Gig of
memory was allocated even though I had set "rss" in
"limits.conf" to 10 Meg.

One thing I can't figure out is why the call to
getrlimit is saying that RLIMIT_DATA is unlimited when
"ulimit -m" is telling me that it is set to 10 Meg.

Let me also add that even if I use "setrlimit()" to
set RLIMIT_DATA to 10 Meg in the program before the
call to malloc(), I am still able to allocate way more
than 10 meg.

Please let me know if anyone has any ideas why I am
seeing this behavior or whether I am simply
misunderstanding the way this should work.

Thank you in advance.

Rigoberto Corujo


       
____________________________________________________________________________________
Looking for a deal? Find great prices on flights and hotels with Yahoo! FareChase.
http://farechase.yahoo.com/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]