在Linux上,我应该如何从/proc/mem的信息中计算可用内存的数量?

5

/proc/mem中有许多字段:我知道我不能只看“MemFree”,因为许多内存实际上是缓存的。所以问题是,如何计算可用内存的数量?

假设:

  • 系统未配置交换空间。
  • 我的“可用内存”定义是当此值为零时,malloc开始失败。

1
没有空闲内存字段的原因是它大多数时候是一个无用的指标:重要的不是你还剩下多少内存,而是你用它来做什么。大量的空闲内存并不能保证任何东西,无论是你可以启动的进程数量还是任何性能方面的表现。 - Bombe
7个回答

8
如果你说系统没有配置swap空间,那么可以通过从/proc/meminfo读取“MemFree”、“Buffers”和“Cached”值并相加来计算可用内存量。
这正是命令“free -m”在“-/+ buffers/cache”行下的“free”所显示的内容。
在Python中,我会这样实现:
 with open('/proc/meminfo', 'rt') as f:
        vals = {}
        for i in f.read().splitlines():
            try:
                name, val = i.split(':')
                vals[name.strip()] = int(val.split()[0])
            except:
                pass

 memfree = vals['MemFree'] + vals['Buffers'] + vals['Cached']

这会返回以千字节为单位的值。

正如其他人所说,malloc不太可能返回null。Linux会过度分配内存,当您开始使用真正无法找到的页面时,OOM killer会启动。


很好,我正是在寻找这个。谢谢。 - lzap

5
我感觉你正在走入错误的道路。你想用这些信息做什么?你想看看是否可以为下一个操作分配足够的内存吗?如果是,你可以调用malloc并检查其返回值。如果返回null,则内存不可用。
请注意,内存是一种高度动态的资源。即使您打开/关闭/proc文件系统的行为可能会导致内存开销。即使您以某种方式成功获取了可以使用malloc()分配的数量,也无法保证在您尝试分配它的瞬间时可用相同数量的内存。

正如smcameron所描述的那样,malloc在许多系统上会进行过度分配,并且永远不会返回null。它只会在你真正开始使用页面时失败。另外:可能有很好的理由想要检查内存状态。例如:如果你编写一个服务器或服务,它与你启动或接受的会话数量几乎呈线性比例关系,通过观察你的空闲内存,你可以停止接受新的会话,从而防止现有会话中断或OOM killer对服务器本身进行不可预测的恶意操作。 - Andre Blum

4

使用源代码吧!

free.c -- 'free' 命令行实用程序的源代码
sysinfo.c -- 查看 meminfo() 方法,了解如何读取 /proc/meminfo 的示例。

虽然读取 /proc 目录相当简单,但预测 malloc 是否会失败却一点也不容易。正如其他人所提到的,过度提交等问题使情况变得复杂。标准的方法是尝试分配所需内存,如果无法成功,则优雅地失败或者降低要求。

如果有足够的时间,阅读这一系列文章是值得的:每个程序员都应该了解的有关内存的知识。


非常好的答案。根据我的经验,'free -m' 命令行实用程序输出中的+/-缓存行可以很好地指示系统接近交换的程度。这个答案教会了我如何从 /proc/meminfo 获取这些信息,避免了在我正在显示内存计量器的定期刷新 Django 仪表板页面中进行昂贵的分叉操作。 - Andre Blum
先生,您逼迫我去学习如何用困难的方式解决问题,现在我更加感激这个答案! - David K

2
据我所知,在Linux上,malloc默认会过度承诺,因此当您期望它失败时,malloc不会失败。您只有在实际触及malloc的内存时才会看到失败,并且可能会唤醒OOM killer。
这可能是有趣的内容(不知道准确性如何)。
但是,在网络上搜索linux malloc overcommit可能会找到一些有趣的东西。具体请参考:http://opsmonkey.blogspot.com/2007/01/linux-memory-overcommit.html

1
以下程序计算 Linux 环境中的内存使用情况。
{
FILE *fp;
char tmpline[1024];
char key[1024];
int line = 0;
int num1 = 0;
int num2 =0;
int val = 0;
int cat = 0;
fp = fopen("/proc/meminfo","r");

fgets(tmpline,256,fp);
sscanf(tmpline,"%*s %d\n",&num1);

fgets(tmpline,256,fp);
sscanf(tmpline,"%*s %d\n",&num2);

printf("toatl mem = %d\n free mem = %d\n",num1,num2);

  val = num1-num2;
printf("Used Mem =%d\n",val );

cat = val*100/num1;
printf("per = %d%\n",cat);

fclose(fp);
return(0);
}

1

试着看一下this之前问题的答案。


0

为回答这个旧帖提供信息,因为我再次来到了这个问题。

free 命令有一个 "available" 条目,/proc/meminfo 中的 "MemAvailable"。

而 man 文档说:

available 估计有多少内存可用于启动新应用程序,而无需交换。与缓存或 free 字段提供的数据不同,该字段考虑了页面缓存,并且并非所有可回收的内存块都将被回收,因为某些项正在使用中(在 /proc/meminfo 中的 MemAvailable,在 3.14 内核上可用,在 2.6.27+ 内核上模拟,在其他情况下与 free 相同)。


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接