views:

664

answers:

6

I want to allocate my buffers according to memory available. Such that, when I do processing and memory usage goes up, but still remains in available memory limits. Is there a way to get available memory (I don't know will virtual or physical memory status will make any difference ?). And method has to be platform Independent as its going to be used on Windows, OS X, Linux and AIX. (And if possible then I would also like to allocate some of available memory for my application, someone it doesn't change during the execution).

+2  A: 

There is no platform independent way to do this, different operating systems use different memory management strategies.

These other stack overflow questions will help:

You should watch out though: It is notoriously difficult to get a "real" value for available memory in linux. What the operating system displays as used by a process is no guarantee of what is actually allocated for the process.

This is a common issue when developing embedded linux systems such as routers, where you want to buffer as much as the hardware allows. Here is a link to an example showing how to get this information in a linux (in C):

mikelong
+5  A: 

Actually, you really shouldn't do that. The amount of memory you grab should be dictated by the work you're doing rather than the amount you have available to you. Do you eat everything in the fridge (icebox?) for dinner just because it's there? I hope not.

The main reason for not doing it is to play nice. Yours is rarely the only process running on the box and, if you try to allocate as much as possible, you may have an adverse effect on others.

Applications should be designed to only allocate what they need, when they need it, and to fail gracefully if the OS decides they've already got too much. By all means, allocate a big chunk at the start if you wish, but don't try to figure out how much it should be based on the memory available.

In any case, there is a disconnect between address space and physical memory in modern operating systems. You can allocate more memory than physically exists and the OS will generally take care of it for you, swapping bits out to secondary storage as required.

paxdiablo
+6  A: 

On UNIX-like operating systems, there is sysconf.

#include <unistd.h>

long getTotalSystemMemory()
{
    long pages = sysconf(_SC_PHYS_PAGES);
    long page_size = sysconf(_SC_PAGE_SIZE);
    return pages * page_size;
}

On Windows, there is GlobalMemoryStatusEx:

#include <windows.h>

long getTotalSystemMemory()
{
    MEMORYSTATUSEX status;
    GetMemoryStatusEx(&status);
    return status.ullTotalPhys;
}

So just do some fancy #ifdefs and you'll be good to go.

And so that I don't get marked down a ton...as others have said, you should not take up all the space available and there are probably better ways to do what you actually want to do. This technique doesn't actually get you the same definition of amount of memory, since some operating systems will use "pages" to mean whatever the hell they want (disk buffers, I/O devices). There is a huge disconnect between the memory space you have access to and the physical bytes in RAM (look up the translation lookaside buffer for just one example of this).

Travis Gockel
I don't think you'll get downvoted for that since it *is* actually useful. We can suggest it's a bad idea as much as we like but, if someone really wants to do something foolish (though I hesitate to use that word), who are we to deny them the tools?
paxdiablo
its not that i want to use up all the memory, its that i don't want to go and load too much data which i can't process with the available memory (i want to remain inside unused or some space which will not probably be accessed by other processes). Again, i don't want to be foolish to want to allocate all the available memory but want to decide what limit should i put on application so it doesn't suck up all memory and get crashed ~___~
Agito
For some operating systems `sysctl` may be a better alternative to `sysconf`. See `man 3 sysctl`.
Paul R
@Agito: On a 32-bit machine, it is safe to assume you have 2GB of space to work with. If the user does not have this much physical memory, the operating system will handle all the virtual memory for you (that's the great thing about PCs). But it is nice to do some heuristics to see how much you *should* take up...but it is a very risky game, since the question "How much memory does this computer have?" is surprisingly poorly defined.
Travis Gockel
@Paul R: I had no idea there was yet another there was yet another way!
Travis Gockel
A: 

Mac OS X example using sysctl (man 3 sysctl):

#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/sysctl.h>

int main(void)
{
    int mib[2] = { CTL_HW, HW_MEMSIZE };
    u_int namelen = sizeof(mib) / sizeof(mib[0]);
    uint64_t size;
    size_t len = sizeof(size);

    if (sysctl(mib, namelen, &size, &len, NULL, 0) < 0)
    {
        perror("sysctl");
    }
    else
    {
        printf("HW.HW_MEMSIZE = %llu bytes\n", size);
    }
    return 0;
}

(may also work on other BSD-like operating systems ?)

Paul R
A: 

The "official" function for this is std::get_temporary_buffer(). However, you might want to test whether your platform has a decent implemenation. I understand that not all platforms behave as desired.

MSalters
A: 

Instead of trying to guess, have you considered letting the user configure how much memory to use for buffers, as well as assuming somewhat conservative defaults? This way you can still run (possibly slightly slower) with no override, but if the user know there is X memory available for the app they can improve performance by configuring that amount.

Mark B