Getting current memory usage

I’ve started gathering the information that I need in order to be able to create the user interface that I want for my PI3 home server.

One of the things I want to do is write a program that will run all the time that the pi is online, it’ll be started and stopped by systemctl just like open vpn etc.

What this program will do is one a second take some vital statistics of my PI and upload it to a MySQL database.   The first part of the information that I wanted to gather is the memory usage of my machine.  In order to be able to properly calculate the ram usage, I needed to get all the different types of memory allocation.  The reason for this is the “used” memory in linux simply means memory that is being used for something, this does not mean that it’s not available.   On the linux OS  you can execute the command “free” to get the amount of memory used

 

free
             total       used       free     shared    buffers     cached
Mem:        234452     217780      16672      10564      36684     100736
-/+ buffers/cache:      80360     154092
Swap:       102396         20     102376

As you can see from the output above. you get lots of different pieces of information.  To find out the true amount of used ram, you can user this formula

 

actual used = total – (free + shared + buffers + cached)

So using the figures above.

actual used = 234452 – ( 16672 + 10564 + 36684 + 100736 )

actual used = 234452 – 164656

actual used = 69796

That’s alot less than the reported 217780 of used Memory.   The reason for this is that shared, buffers and cached memory can be dumped by the operating system to make way for other processes.  So, on my PI, (It’s a Model B 256MB ram) it that will happen sooner than on a PI2 or PI3, or even a later PI.

 

There are several ways to get at the system memory using raspbian.

 

cat /proc/meminfo
MemTotal: 234452 kB
MemFree: 16124 kB
MemAvailable: 128144 kB
Buffers: 37116 kB
Cached: 100736 kB

Shmem:             10564 kB

SwapTotal: 102396 kB
SwapFree: 102376 kB

 

It’s all there at loads more too.  however, it’s shown in kB  which means that there’s information missing, it’s rounded to the nearest kB, and being pedantic I want the exact number of bytes.

 

What about the c command sysinfo?

 

This link provides the details about sysinfo.  Upon reading, it looks promising, however there’s a fatal floor in this plan.  The cached memory isn’t reported, which kinda messes up the plan completely.

 

This really leaves me with one option that I can see so far.  The linux command “free -b”  the -b means return the values as bytes, which is perfect, and the output is similar to above.

 

free -b
             total       used       free     shared    buffers     cached
Mem:     240078848  223744000   16334848   10817536   38113280  103157760
-/+ buffers/cache:   82472960  157605888
Swap:    104853504      20480  104833024

That's the figures that I'm after, just need to get at the them now.

So, to do that here's a little c method that I wrote.

struct MemoryUsage{
 unsigned long RamTotal;
 unsigned long RamActualUsed;
 unsigned long RamUsed;
 unsigned long RamFree;
 unsigned long RamShared;
 unsigned long RamBuffers;
 unsigned long RamCached;
 unsigned long SwapTotal;
 unsigned long SwapFree;
 unsigned long SwapUsed;
};

struct MemoryUsage GetMemoryUsage()
{
 struct MemoryUsage memoryUsage;
 
 memoryUsage.RamTotal = 0;
 
 FILE *fp;
 
 fp = popen("free -b","r");
 if (fp == NULL)
 {
 perror("Error opening file");
 exit(EXIT_FAILURE);
 }
 
 char str[1024];
 int lineNo = 0;
 char token[1024];
 
 while (fgets(str, sizeof(str)-1, fp) != NULL) {
 lineNo++;
 
 if (lineNo == 2)
 {
 sscanf( str, "%s %u %u %u %u %u %u",
 token,
 &memoryUsage.RamTotal,
 &memoryUsage.RamUsed,
 &memoryUsage.RamFree,
 &memoryUsage.RamShared,
 &memoryUsage.RamBuffers,
 &memoryUsage.RamCached
 );
 }
 if (lineNo == 4)
 {
 sscanf( str, "%s %u %u %u",
 token,
 &memoryUsage.SwapTotal,
 &memoryUsage.SwapUsed,
 &memoryUsage.SwapFree
 );
 }
 }
 
 fclose(fp);

 memoryUsage.RamActualUsed = memoryUsage.RamTotal - ( memoryUsage.RamFree + memoryUsage.RamShared + memoryUsage.RamCached );
 
 return memoryUsage;
}


To call it, all you need to do is...

struct MemoryUsage memoryUsage;
 memoryUsage = GetMemoryUsage();

And at this point, you should have all the memoryinformation that you could want.  Including the actual used ram from the formula about.

Leave a Reply

Your email address will not be published. Required fields are marked *