正确计算linux系统内存使用率

原创
2017/03/22 14:43
阅读数 7.8K

free命令

[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          3729       3487        242          0        206       2502
-/+ buffers/cache:        778       2951
Swap:         3871         11       3860
  • 第一行(可以理解为从内核态角度来看内存分配)

    total = used + free : 3729 = 3487 + 242

指标 作用
total 总物理内存大小
used 已分配的大小,注意, 对操作系统内核来说任何被使用的内存都是used
free 未分配的物理内存的大小
shared 共享内存大小, 主要用于进程间通信
buffers 主要用于块设备数据缓冲, 例如记录文件系统的metadata(目录,权限等信息)
cached 主要用于文件内容缓冲
  • 第二行 (可以理解为从用户态的角度来看内存分配)
指标 作用
-buffers/cache used内存数: 第一行的 used - buffers - cached = 3487 - 206 - 2502 = 779
+buffers/cache free内存数: 第一行的 free + buffers + cached = 242 + 206 + 2502 = 2950

total = (-buffers/cache) + (+buffers/cache ) = 778 + 2591 = 3729

对操作系统来讲是Mem参数中 buffers 和 cached 是被使用的, 但对应用程序而言: buffers 和cached是可用的,因为buffer/cached是为了提高程序执行的性能,当程序使用内存时,buffer/cached会很快被使用。


/proc/meminfo

[root@localhost ~]# cat /proc/meminfo
MemTotal:        3819496 kB
MemFree:          248252 kB
Buffers:          211068 kB
Cached:          2562864 kB
SwapCached:          816 kB
Active:          1561800 kB
Inactive:        1690932 kB
Active(anon):     170024 kB
Inactive(anon):   308816 kB
Active(file):    1391776 kB
Inactive(file):  1382116 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       3964924 kB
SwapFree:        3953364 kB
Dirty:                40 kB
Writeback:             0 kB
AnonPages:        478032 kB
Mapped:            13736 kB
Shmem:                32 kB
Slab:             265272 kB
SReclaimable:     198708 kB
SUnreclaim:        66564 kB
KernelStack:        2400 kB
PageTables:         3928 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     5874672 kB
Committed_AS:     901592 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      553792 kB
VmallocChunk:   34359179368 kB
HardwareCorrupted:     0 kB
AnonHugePages:    407552 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        8224 kB
DirectMap2M:     4083712 kB

linux 内存管理机制
linux的内存管理机制的思想包括(不敢说就是)内存利用率最大化。 内核会把剩余的内存申请为cached, 而cached不属于free范畴。 当系统运行时间较久,会发现cached很大, 对于有频繁文件读写操作的系统,这种现象会更加明显。

直观的看,此时free的内存会非常小,但并不代表可用的内存小,当一个程序需要申请较大的内存时,如果free的内存不够, 内核会把部分cached的内存回收,回收的内存再分配给应用程序。所以对于linux系统,可用于分配的内存不只是free的内存, 还包括cached的内存(其实还包括buffers)。

通过定时采集 /proc 系统内的meminfo 文件来获取当前内存使用情况:

proc文件系统是一个伪文件系统,它只存在内存中,而不占用外存空间。 它以文件系统的方式为访问系统内核数据的 操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程, 是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需要信息并提交的 采集流程图。

指标 作用
MemTotal 总内存大小
MemFree 空闲内存大小
buffers/cached 磁盘缓存的大小

Buffers 和 Cached的区别: Buffers 是指用来给块设备做的缓冲大小,他只记录文件系统的metadata以及 tracking in-flight pages. cached 是用来给文件做缓冲。

buffers 是值存储目录里面有什么内容,权限等等。 而cached直接用来记忆我们打开的文件,比如先后执行两次命令#man X ,你就可以明显的感觉到第二次的开打的速度快很多。 而buffers随时都在增加,比如先后两次使用ls /dev后,就会发现第二次执行的速度会较第一次快。 这就是buffers/chached的区别。

  • 以内核态来讲, buffers 和 cached 是已经被使用的:
MemUsed  = MemTotal - MemFree = 3819496 - 248252 = 3571244 KB = 3487 MB
  • 以用户态来讲
free = MemFree + Buffers + Cahched = 248252 + 211068 + 2562864 = 3022184 KB = 2951 MB
  • 本着监控应用对物理内存使用情况的目的采集,计算方法:
MemUsedPrec = 100*(MemTotal - MemFree - Buffers - Cahched)/MemTotal
int GetMemOccupy(tMemInfoStr& tMemInfo)
{
	FILE* fpMemInfo = fopen("/proc/meminfo", "r");
	if (NULL == fpMemInfo)
	{
		ADP_LOG(ADP_ERROR, "[GetMemOccupy] fopen /proc/meminfo failed!\n");
		return 1;
	}

	int i = 0;
	int value;
	char name[1024];
	char line[1024];
	int nFiledNumber = 2;
	int nMemberNumber = 7;
	while (fgets(line, sizeof(line) - 1, fpMemInfo))
	{
		if (sscanf(line, "%s%u", name, &value) != nFiledNumber)
		{
			continue;
		}
		if (0 == strcmp(name, "MemTotal:"))
		{
			++i;
			tMemInfo.dwMemTotal = value;
		}
		else if (0 == strcmp(name, "MemFree:"))
		{
			++i;
			tMemInfo.dwMemFree = value;
		}
		else if (0 == strcmp(name, "Buffers:"))
		{
			++i;
			tMemInfo.dwBuffers = value;
		}
		else if (0 == strcmp(name, "Cached:"))
		{
			++i;
			tMemInfo.dwCached = value;
		}
		else if (0 == strcmp(name, "SwapCached:"))
		{
			++i;
			tMemInfo.dwSwapCached = value;
		}
		else if (0 == strcmp(name, "SwapTotal:"))
		{
			++i;
			tMemInfo.dwSwapTotal = value;
		}
		else if (0 == strcmp(name, "SwapFree:"))
		{
			++i;
			tMemInfo.dwSwapFree = value;
		}

		if (i == nMemberNumber)
		{
			break;
		}
	}

	tMemInfo.dwMemUsed = tMemInfo.dwMemTotal - tMemInfo.dwMemFree;
	tMemInfo.fMemUseRate = (unsigned int)(((float)(tMemInfo.dwMemUsed - tMemInfo.dwCached - tMemInfo.dwBuffers)/((float)tMemInfo.dwMemTotal)) * 100);
	if (tMemInfo.fMemUseRate < 0)
	{
		tMemInfo.fMemUseRate = 0;
	}

	fclose(fpMemInfo);
	gettimeofday(&(tMemInfo.tCapTime), NULL);
	return (i == nMemberNumber);
}
展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
在线直播报名
返回顶部
顶部