在代码中实现对各进程内存的监控

核心观点(在代码上实现对进程的内存监控原理):

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版权协议,转载请附上原文出处链接和本声明。