Stupid C memory allocation query - SGI

This is a discussion on Stupid C memory allocation query - SGI ; Hi Guys, Simple one, this: I'm driving some 'legacy' SCSI hardware, shall we say, hardware and to do this we use our own driver. I've been watching some of our SGIs lately and they're going into swap when in all ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: Stupid C memory allocation query

  1. Stupid C memory allocation query

    Hi Guys,

    Simple one, this: I'm driving some 'legacy' SCSI hardware, shall we say,
    hardware and to do this we use our own driver.
    I've been watching some of our SGIs lately and they're going into swap
    when in all honesty they have plenty of RAM. They run no applications
    other than our own.

    Now, I traced it down to a bunch of free()s that don't seem to have
    immediate effect. The actual freeing is delayed until later on in
    execution, by which time we've malloc'd more and the machine is in swap.

    This little bit of C demonstrates this perfectly. I'm compiling with gcc
    3.4, but my feeling is that this caused by IRIX as under Linux this
    works fine. I think there's possibly a tunable parameter somewhere. Anyone?


    #include
    #include
    #include

    int main(int argc, char **argv)
    {
    unsigned char *bigbuf1, *bigbuf2;
    int megs = 40;
    int size = 1024 * 1024;

    sleep(5);

    printf("allocating bigbuf1\n");
    bigbuf1 = malloc(megs * size);
    if(bigbuf1 == NULL)
    {
    printf("allocate failed\n");
    exit(1);
    }

    sleep(5);

    printf("allocating bigbuf2\n");
    bigbuf2 = malloc(megs * size);
    if(bigbuf2 == NULL)
    {
    printf("allocate failed\n");
    exit(1);
    }

    sleep(5);

    printf("freeing bigbuf1\n");
    free(bigbuf1);

    sleep(5);

    printf("freeing bigbuf2\n");
    free(bigbuf2);

    sleep(5);
    return 0;
    }

    Thanks
    Simon


  2. Re: Stupid C memory allocation query

    In article <446c8c64$0$2585$db0fefd9@news.zen.co.uk>,
    Simon Burley wrote:
    >I've been watching some of our SGIs lately and they're going into swap
    >when in all honesty they have plenty of RAM.


    >Now, I traced it down to a bunch of free()s that don't seem to have
    >immediate effect. The actual freeing is delayed until later on in
    >execution, by which time we've malloc'd more and the machine is in swap.


    >This little bit of C demonstrates this perfectly. I'm compiling with gcc
    >3.4, but my feeling is that this caused by IRIX as under Linux this
    >works fine. I think there's possibly a tunable parameter somewhere. Anyone?


    There is no tunable parameter for this. You have a classic memory
    fragmentation problem. You need to replace your memory allocator
    with one more suitable for your purposes, or else you need to
    switch to using mmap() or shared memory segments for your memory allocation.

    It is standard Unix that malloc()/calloc() memory will not be given back
    to the OS unless you specifically tell it to be given back.
    Classically malloc()/calloc() attempt to reuse existing free()'d memory
    but ask the OS for more memory if they cannot find a previously-free()'d
    block that satisfies the allocation strategy. The mechanism for
    requesting more memory from the OS or returning memory to the OS
    were traditionally the brk() and sbrk() calls {NB: neither are
    part of standard C nor POSIX.1}. brk() and sbrk() traditionally
    can only move the endpoint of allocated memory, and cannot create
    "holes" in memory -- e.g., you can only return a particular array
    back to the OS if you happen to know that it is the *last* thing
    in memory [which is difficult to prove if you haven't written your
    own memory allocator, since even routines such as printf() can
    malloc() memory.]


    What -might- work for you is to use the "swap -a -v" command to add
    virtual swap space. See the swap(1M) man page for more information
    about the potential pitfalls of that.


    > This little bit of C demonstrates this perfectly.


    For me it just allocates memory and frees it, with no problems.
    40 megabytes twice is trivial these days. Should the program
    have been accompanied by instructions as to how to monitor it
    to see the effect you were looking for?

  3. Re: Stupid C memory allocation query

    In article <446c8c64$0$2585$db0fefd9@news.zen.co.uk>,
    Simon Burley wrote:

    : This little bit of C demonstrates this perfectly. I'm compiling with gcc
    : 3.4, but my feeling is that this caused by IRIX as under Linux this
    : works fine. I think there's possibly a tunable parameter somewhere. Anyone?

    As Walter said, it's a matter of how malloc() is implemented. Linux (glibc,
    really) specifically uses a mixed-style allocator which uses brk()/sbrk() for
    small allocations, and mmap() for large allocations. This allows it to return
    larger allocations to the system sooner.

    A simple brk/sbrk-only allocator will tend to run into memory fragmentation
    problems earlier because, as Walter said, there is no way to return the "holes"
    for reuse in other processes.

    A simple mmap-only allocator will tend to run into MM performance problems due
    to the large number of maps and mapping calls, as well as other types of
    fragmentation problems due to the large number of unused "tails" at the end of
    mapped pages.

    You should be able to port the glibc malloc routines to your project, there
    shouldn't be much linux-specific code that can't be reproduced in IRIX (though
    there will be linux-specific tuning which might need a few tweaks for best
    performance).

    Of course, it's LGPL, so read up on the licence and be sure that it's compatible
    with how you intend to integrate the code.


    Cheers - Tony 'Nicoya' Mantler

    --
    Tony 'Nicoya' Mantler - Master of Code-fu
    -- nicoya@ubb.ca -- http://www.ubb.ca/ --

  4. Re: Stupid C memory allocation query

    Walter Roberson wrote:

    >>This little bit of C demonstrates this perfectly.

    >
    >
    > For me it just allocates memory and frees it, with no problems.
    > 40 megabytes twice is trivial these days. Should the program
    > have been accompanied by instructions as to how to monitor it
    > to see the effect you were looking for?


    Yes. Apologies.

    After each printf does it's thing, use ps -efl|grep and
    watch the SZ and RSS columns.

    You'll notice that SZ doesn't decrease immediately at each free()
    Since brk()/sbrk() is not going to do what I need (the array I want to
    hand back to the OS is just about never going to be the last thing in
    memory) I'll look into virtual swap, more RAM, or using my own allocator.

    The 40MB example is just that, btw. The real arrays I'm dealing with are
    *much* larger, hence my concern.

    Thanks for your explanation. And thanks to Tony, too.

    Thanks
    Simon


+ Reply to Thread