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).
There is no platform independent way to do this, different operating systems use different memory management strategies.
These other stack overflow questions will help:
- http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c
- http://stackoverflow.com/questions/1674652/c-c-memory-usage-api-in-linux-windows
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):
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.
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 #ifdef
s 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).
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 ?)
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.
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.