Linux system USES C program to output the memory occupation information of a process

  • 2020-06-23 02:37:13
  • OfStack

preface

We have all encountered a situation, in the actual work sometimes need the program to print out the memory usage of a process for reference, the following introduces a process through Linux pseudo-file system /proc calculation of a process memory usage of the program implementation method.

Implementation analysis

First of all, why there are so-called pseudo file? Linux system file types can be roughly divided into three categories: normal files, directories and false documents. Pseudo file is not used to store data, so these files do not take up disk space, only exist in memory. / proc allows you to interact with the kernel internal data, access to useful information on the process.

The following are the four files under 1 /proc: /proc/stat , /proc/meminfo , /proc/<pid>/stat , /proc/<pid>/status .

/proc/stat store the cpu time of the system, which contains information on all cpu activities.


cpu 72389 2891 16811 1148664 31374 0 67 0 0 0
cpu0 17608 452 3786 288899 6210 0 30 0 0 0
cpu1 18724 926 4598 285844 8911 0 15 0 0 0
cpu2 16803 658 3726 288710 7220 0 7 0 0 0
cpu3 19254 855 4700 285209 9032 0 13 0 0 0
...
...
...

/proc/meminfo The memory information of the system is stored, and the information represented by the name of each variable in the file is known.


MemTotal: 4046236 kB
MemFree:  1054440 kB
MemAvailable: 2460060 kB
Buffers:  359688 kB
Cached:  1158056 kB
SwapCached:  0 kB
Active:  2020096 kB
Inactive:  677948 kB
Active(anon): 1181376 kB

...
...
...

/proc/<pid>/stat Store cpu information for a process


2476 (firefox) S 1773 1910 1910 0 -1 4210688 3413511 1712 757 1 45466 4629 2 7 20 0 57 0 20381 1774743552 150565 18446744073709551615 94844693012480 94844693126372 140732961864784 140732961858304 139747170914269 0 0 4096 33572079 0 0 0 17 2 0 0 1178 0 0 94844695226592 94844695228536 94844713955328 140732961867643 140732961867668 140732961867668 140732961869791 0

/proc/<pid>/status Store cpu information for a process and 1 general information


Name: firefox
State: S (sleeping)
Tgid: 2476
Ngid: 0
Pid: 2476
PPid: 1773
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 24 27 30 46 108 124 1000 
NStgid: 2476
NSpid: 2476
NSpgid: 1910
NSsid: 1910
VmPeak: 1722812 kB
VmSize: 1690920 kB
VmLck:   0 kB
VmPin:   0 kB
VmHWM: 684048 kB
VmRSS: 600324 kB
VmData: 993040 kB
VmStk:  192 kB
...
...
...

The above data can be obtained by reading the file. The corresponding data can be calculated according to the needs of my own experiment, such as pmem = VmRSS/MemTotal*100 And so on.

The sample code

Here is a simple example of the c code implementation that gets the actual memory occupied by a process at the current moment.


//get_mem.h
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <assert.h>
#define VMRSS_LINE 21//VMRSS Where the line ,  note : Depending on the system , The location may be different .
#define pid_t int
int get_phy_mem(const pid_t p)
{
 char file[64] = {0};// The file name 
 FILE *fd;   // Definition file pointer fd
 char line_buff[256] = {0}; // Read row buffer 
 sprintf(file,"/proc/%d/status",p);
 fprintf (stderr, "current pid:%d\n", p);
 fd = fopen (file, "r"); // In order to R Read opens the file and assigns the pointer fd
 // To obtain vmrss: Actual physical memory footprint 
 int i;
 char name[32];// Store project name 
 int vmrss;// Storage memory 
 // read VmRSS this 1 The data 
 for (i=0;i<VMRSS_LINE-1;i++)
 {
  char* ret = fgets (line_buff, sizeof(line_buff), fd);
 }
 char* ret1 = fgets (line_buff, sizeof(line_buff), fd);
 sscanf (line_buff, "%s %d", name,&vmrss);
 fprintf (stderr, "====%s : %d====\n", name,vmrss);
 fclose(fd);  // Close the file fd
 return vmrss;
}
int get_rmem(pid_t p)
{
 return get_phy_mem(p);
}
int get_total_mem()
{
 const char* file = "/proc/meminfo";// The file name 
 FILE *fd;   // Definition file pointer fd
 char line_buff[256] = {0}; // Read row buffer 
 fd = fopen (file, "r"); // In order to R Read opens the file and assigns the pointer fd
 // To obtain memtotal: Total memory footprint size 
 int i;
 char name[32];// Store project name 
 int memtotal;// Store the peak memory size 
 char*ret = fgets (line_buff, sizeof(line_buff), fd);// read memtotal this 1 The data ,memtotal In the first 1 line 
 sscanf (line_buff, "%s %d", name,&memtotal);
 fprintf (stderr, "====%s : %d====\n", name,memtotal);
 fclose(fd);  // Close the file fd
 return memtotal;
}

Test file:


#include "get_mem.h"
int main()
{
int list[1024];
for(int i = 0; i < 1024; i++)
 list[i] = i;
int mem = get_rmem(getpid());

}

conclusion


Related articles: