核心观点(在代码上实现对进程的内存监控原理):
1通过命令 ps -aux来确认各进程PID
2通过命令 cat /proc/PID/status来获取各个进程PID下的内存信息
3通过grep命令来对命令进行信息筛选
4通过linux上的 popen() fread()函数来运行命令并获取命令的返回内容
5将第四点的内容通过printf进行输出(下面代码log_printf() 是对printf的一层封装)
最后可以通过timer定周期执行下面的函数 ProcessMemCheck(void)来实现定周期检查进程内存的目的
void ProcessMemCheck(void)
{
/*----- Test Variable -------------------------------------------*/
/*----- Local Variable -------------------------------------------*/
unsigned char mem_free_buf[60]; /*存放free管道命令返回值 */
unsigned char mem_Proc_Count_buf[10]; /* 获取proc下进程数量 */
unsigned char mem_Proc_CountNum_buf[10]; /* 获取proc下各个进程PID */
unsigned char mem_ProcessName_buf[20]; /* 获取proc下各个进程Name */
unsigned char mem_VmRSS_buf[20]; /* 获取proc下各个进程VmRSS */
unsigned char mem_VmSize_buf[20]; /* 获取proc下各个进程VmSize */
/*用于存放各命令buffer */
unsigned char mem_Proc_CountNum_buf_CMD[50];
unsigned char mem_ProcessName_buf_CMD[50];
unsigned char mem_VmRSS_buf_CMD[50];
unsigned char mem_VmSize_buf_CMD[50];
unsigned int auhCount = INIT_0;
/* 各个管道的指针 */
FILE *fp_free=NULL;
FILE *fp_Proc_Count=NULL;
FILE *fp_Proc_Num=NULL;
FILE *fp_ProcessName=NULL;
FILE *fp_VmRSS=NULL;
FILE *fp_VmSize=NULL;
/*----- Function Logic -------------------------------------------*/
/* step0:check free 下的内存值 */
memset(mem_free_buf,0,sizeof(mem_free_buf));
fp_free = popen("free |grep Mem|tr -s ' '","r"); /* 命令Tips:tr -s '' 用于将连续空格替换为一个空格,目的是减少返回内容长度 */
if(fp_free != NULL)
{
fread(mem_free_buf,INIT_1,sizeof(mem_free_buf),fp_free);
pclose(fp_free);
log_printf(TRUE,("Free: %s \r\n",mem_free_buf));
}else{
log_printf(TRUE,("memcheck step 0 open error!!!!!!\n"));
}
/* check proc-pid-status下的内存值 */
/* step1:首先获取proc下的进程数量 */
memset(mem_Proc_Count_buf,0,sizeof(mem_Proc_Count_buf));
fp_Proc_Count = popen("ls -1 /proc/ |egrep '[[:digit:]]'|wc -l","r");/* 命令Tips:egrep 筛选数字相关,wc 用于计数 */
if(fp_Proc_Count != NULL)
{
fread(mem_Proc_Count_buf,INIT_1,sizeof(mem_Proc_Count_buf),fp_Proc_Count);
pclose(fp_Proc_Count);
printf("str: %s atoi:%d\n",mem_Proc_Count_buf,atoi(mem_Proc_Count_buf));
for(auhCount = INIT_0;auhCount < atoi(mem_Proc_Count_buf);auhCount++)
{
/* step2:在for循环下取得各个进程的PID值 */
memset(mem_Proc_CountNum_buf,0,sizeof(mem_Proc_CountNum_buf));
memset(mem_Proc_CountNum_buf_CMD,0,sizeof(mem_Proc_CountNum_buf_CMD));
sprintf(mem_Proc_CountNum_buf_CMD,"ls -1 /proc/ |egrep '[[:digit:]]'|sed -n '%dp'|awk -v ORS='' '{print $0}' ",auhCount);/* 命令Tips:sed用于筛选行数,awk -v ORS 取消了最后的换行符 */
fp_Proc_Num = popen(mem_Proc_CountNum_buf_CMD,"r");
if(fp_Proc_Num != NULL)
{
fread(mem_Proc_CountNum_buf,INIT_1,sizeof(mem_Proc_CountNum_buf),fp_Proc_Num);
pclose(fp_Proc_Num);
/* step3:在对应PID下的status下取得VmRSS */
memset(mem_ProcessName_buf,0,sizeof(mem_ProcessName_buf));
memset(mem_VmRSS_buf,0,sizeof(mem_VmRSS_buf));
memset(mem_VmSize_buf,0,sizeof(mem_VmSize_buf));
sprintf(mem_VmRSS_buf_CMD,"cat /proc/%s/status |grep '^VmRSS' |awk -v ORS='' '{print $2}'",mem_Proc_CountNum_buf);
fp_VmRSS = popen(mem_VmRSS_buf_CMD,"r");
if(fp_VmRSS != NULL)
{
fread(mem_VmRSS_buf,INIT_1,sizeof(mem_VmRSS_buf),fp_VmRSS);
pclose(fp_VmRSS);
/* step4:因为有部分PID不是真正的进程,所以要对没有VmRSS及VmSize的项进行剔除 */
if(strlen(mem_VmRSS_buf)==0)
{
continue;
}else{
/* step5:取得对应进程的Name */
sprintf(mem_ProcessName_buf_CMD,"cat /proc/%s/status |grep '^Name' |awk -v ORS='' '{print $2}'",mem_Proc_CountNum_buf);
fp_ProcessName = popen(mem_ProcessName_buf_CMD,"r");
if(fp_ProcessName != NULL)
{
fread(mem_ProcessName_buf,INIT_1,sizeof(mem_ProcessName_buf),fp_ProcessName);
pclose(fp_ProcessName);
/* step6:取得对应进程的VmSize */
sprintf(mem_VmSize_buf_CMD,"cat /proc/%s/status |grep '^VmSize' |awk -v ORS='' '{print $2}'",mem_Proc_CountNum_buf);
fp_VmSize = popen(mem_VmSize_buf_CMD,"r");
if(fp_VmSize != NULL)
{
fread(mem_VmSize_buf,INIT_1,sizeof(mem_VmSize_buf),fp_VmSize);
pclose(fp_VmSize);
/* step7:最终输出log 内容包括 Name PID VmRSS VmSize */
log_printf(TRUE,("Process:%s,PID:%d ,VmRSS:%skB,VmSize:%skB \n",mem_ProcessName_buf,auhCount,mem_VmRSS_buf,mem_VmSize_buf));
}
}
}
}
}
}
}else{
log_printf(TRUE,("memcheck step 1 open error!!!!!!\n"));
}
/* PS: 释放buff/cache相关 */
system("sync && echo 1 > /proc/sys/vm/drop_caches ");
system("sync && echo 2 > /proc/sys/vm/drop_caches ");
system("sync && echo 3 > /proc/sys/vm/drop_caches ");
}版权声明:本文为qq_34597963原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。