sysinfo 系统调用未返回正确的 freeram 值

Posted

技术标签:

【中文标题】sysinfo 系统调用未返回正确的 freeram 值【英文标题】:sysinfo system call not returning correct freeram value 【发布时间】:2012-02-17 17:55:51 【问题描述】:

我最近使用 sysinfo 系统调用编写了以下 C 代码来显示系统统计信息,让我感到有趣的是 sysinfo 结构的 freeram 变量不返回可用 RAM 的数量,而是返回当前的 RAM 使用情况。我不得不使用一种变通方法通过从 totalram 中减去 freeram 来显示正确的值。我试过用谷歌搜索这个特定的变量,但无济于事。对这种奇怪行为的任何洞察都会非常有帮助。

/*
 * C program to print the system statistics like system uptime, 
 * total RAM space, free RAM space, process count, page size
 */

#include <sys/sysinfo.h>    // sysinfo
#include <stdio.h>
#include <unistd.h>     // sysconf
#include "syscalls.h"       // just contains a wrapper function - error

int main()

    struct sysinfo info;

    if (sysinfo(&info) != 0)
        error("sysinfo: error reading system statistics");

    printf("Uptime: %ld:%ld:%ld\n", info.uptime/3600, info.uptime%3600/60, info.uptime%60);
    printf("Total RAM: %ld MB\n", info.totalram/1024/1024);
    printf("Free RAM: %ld MB\n", (info.totalram-info.freeram)/1024/1024);
    printf("Process count: %d\n", info.procs);
    printf("Page size: %ld bytes\n", sysconf(_SC_PAGESIZE));

    return 0;

【问题讨论】:

info.freeram 在我的盒子上正常工作。摆脱"syscalls.h" syscalls.h 无论如何都不会影响代码。请参阅下面@shadyabhi 的答案。 【参考方案1】:

“免费内存”字段对大多数人来说毫无意义。最接近真正的“免费内存”值的是从/proc/meminfo 中获取字段并从MemTotal 中减去Committed_AS。如果交换正在使用,结果可能是负面的(这意味着分配的内存比物理内存中容纳的更多);如果您也想将交换计入内存,只需使用 MemTotal+SwapTotal 作为您的总和。

【讨论】:

@r 请解释一下为什么它没有意义。 任何现代系统都旨在始终保持所有内存“处于使用状态”,但使​​用它和提交它是有区别的长期用于无法丢弃或同步到磁盘的数据。您看到的大多数“正在使用”的内存实际上是磁盘上文件的缓存副本。其中一些是当前正在执行的程序,另一些是内核预期可能会再次读取的文件。另一方面,已提交内存存储磁盘上任何地方都不存在的实际变量数据(除非它被交换)。 阅读linuxatemyram.com/index.html后终于找到了完整的答案:-) 不错的链接,有趣,+1。 :-) @SRG:真的不是。这是一个估计值,包括在禁用过度使用时只能由内核用于缓存或内核资源的内存,如果在启用过度使用时使用那么多,这将导致 OOM-killing。 Commit_Limit-Committed_AS 是您可以安全分配的限制。【参考方案2】:

删除

#include "syscalls.h"

可能是,您从某个地方借用了代码并进行了编辑。双引号用于导入非官方的头文件。那个自定义头文件并不是真正需要的。

不需要。您的代码将运行良好。

在我的电脑上,$free -m 的 freeram 值与程序的 info.freeram 匹配。显然,freeram 并不是你想象的那样。

阅读更多关于http://www.redhat.com/advice/tips/meminfo.html

MemFree 是可用内存,MemFree + Buffers + Cached 是可用内存(你想要的)。所以,你只是错误地理解了 freeram 这个词。

【讨论】:

如果您尝试运行我上面发布的代码,那绝对是正确的,因为代码中存在解决方法: printf("Free RAM: %ld MB\n", (info.totalram -info.freeram)/1024/1024);尝试替换为 printf("Free RAM: %ld MB\n", info.freeram/1024/1024); syscalls.h 也只包含一个包装函数错误。 同意你的观点,free -m 的行为类似。我浏览了您提供的链接,但还不明白为什么 freeram/MemFree 给出的值接近 GNOME 系统监视器显示的内存 used 统计信息;这不应该反过来吗? (或者换句话说,为什么freeram不等于我系统上的free ram?) @k4rtik 正如我所说,在 Gnome 系统监视器中,它显示 MemFree + Buffers + Cached。 (我已经在回答中提到过) 在阅读linuxatemyram.com/index.html后终于找到了完整的答案【参考方案3】:

你需要乘以 mem_unit。

【讨论】:

以上是关于sysinfo 系统调用未返回正确的 freeram 值的主要内容,如果未能解决你的问题,请参考以下文章

MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……

模拟系统调用错误

Laravel 8 API 调用未正确返回验证错误

返回时dll挂钩未正确更新调用堆栈

挂在 _dl_sysinfo_int80 上的多线程应用程序

使用 open 系统调用未正确设置文件权限