I'm trying to monitor available memory of the Linux system in my C code to handle near out-of-memory situation and I tried to do
long available_mem = sysconf(_SC_AVPHYS_PAGES) * pagesize;
but it appears that if I run this same code repeatedly, the value matches free memory reported by sysinfo()
instead of MemAvailable
from /proc/meminfo
. Is this expected? (If I actually try to use even close to available_mem
worth of memory, the system will be swapping a lot so it seems that it doesn't match the actually available memory.)
Is there a way to get current value of MemAvailable
(or close realtime approximation) without parsing strings from /proc/meminfo
?
It turns out that GNU libc documentation lies... According to the libc documentation
sysconf (_SC_AVPHYS_PAGES)
The value returned for _SC_AVPHYS_PAGES is the amount of memory the application can use without hindering any other process (given that no other process increases its memory usage). The value returned for _SC_PHYS_PAGES is more or less a hard limit for the working set. If all applications together constantly use more than that amount of memory the system is in trouble.
However, the actual source code of sysconf()
says
636 case _SC_AVPHYS_PAGES:
637 return __get_avphys_pages ();
and the definition of __get_avphys_pages()
reads
328 long int
329 __get_avphys_pages (void)
330 {
331 struct sysinfo info;
332
333 __sysinfo (&info);
334 return sysinfo_mempages (info.freeram, info.mem_unit);
335 }
So obviously the returned value is not "the amount of memory the application can use without hindering any other process" which would match MemAvailable
from /proc/meminfo
but amount of .freeram
from kernel system call sysinfo()
.
So the end result is not expected according to the documentation, but it's expected according to the actual implementation.