安装了多少物理内存?

2020-11-29 22:35:46

我经常想计算安装在运行Linux的系统中的物理内存的确切数量,今天我终于偶然发现了令人满意的解决方案:在/ sys / devices / system / memory下查看。我知道我已经在该系统中安装了16GB(或者如果您愿意,可以选择GiB)的内存。我一直觉得令free -greport之类的命令只有15GB作为“安装的总内存”感到沮丧。我知道为什么会这样-某些总内存由系统保留,有些由内核占用,而只有其余部分可供应用程序使用。那是/ proc / meminfo中报告为“ MemTotal”的数字,这是其他所有东西使用的数字。对于大多数实际目的,这是重要的数字。 $ grep MemTotal:/ proc / meminfo MemTotal:16283212 kB $ echo $(($(getconf PAGE_SIZE)* $(getconf _PHYS_PAGES)/ 1024))16283212

我知道获得答案的另一种方法:dmidecode将报告每个“内存设备”的确切大小。例如,mysystem安装了2×8GB DIMM:不幸的是,您必须具有root用户访问权限才能运行dmidecode,输出相当冗长(尝试仅运行“ dmidecode”),尽管在我尝试过的所有地方都可以使用,从来没有完全确定过它对不同的体系结构和系统配置的适应性。这不是一个真正令人满意的解决方案。但是看看我今天遇到的困难:$ cd / sys / devices / system && echo $(($(grep -x在线内存/内存[0-9] * / state | wc -l)* 0x $(cat内存/ block_size_bytes )/ 1024 ** 3))16

完善! / sys / devices / system / memory下的每个memoryN子目录都代表一个block_size_bytes物理内存块,如果将所有内容相加,则得出正确的总数。在我的系统上,块大小为0x8000000字节,即128MB,并且有128个子目录,总计16GB。在具有可热插拔RAM的系统上,内存N /状态可能为“离线”,因此我将grep设置为“在线”以确保不在将子目录计入总数之前。 (似乎可以“回传离线”状态文件以更改状态,但我不敢尝试。)有趣的是,子目录不是memory0到memory127,而是memory0到memory20和memory32到memory138。数字中的11块孔必须有一些解释,但我不知道它是什么。如果最近一次重新启动不是不久之前,您可能会在dmesg中找到以下消息:内存:可用16265512K / 16659852K(10252K内核代码,1222K rwdata,3252K rodata,1552K init,656K bss,394340Kreserved,0K cma保留)

这并不能告诉您确切的物理内存多少,但是这些数字很有趣。 16265512K对应于MemTotal,如果添加了394340K的保留内存,则将达到16659852K。整洁,但是smidgen少于预期的16777216K不到500MB。那是我碰巧保存的一些旧的dmesg输出。但是,在撰写本文时,我对系统会说些什么感到好奇,然后重新启动进行检查。令我惊讶的是,我无法理解结果:#uname -r5.8.0-0.bpo.2-amd64#dmesg -T | grep内存:[Fri Nov 27 12:37:05 2020]内存:2627884K / 16659852K可用(12291K内核代码,1292K rwdata,4060K rodata,1632K init,1864K bss,442442K保留,0K cma保留)

16659852K相同,括号中的其他数字看起来合理(对于不同的内核),但是2627884K只有2.5GB!尽管有这个奇怪的结果,/ proc / meminfo中的值看起来还是不错的:#cat / proc / meminfo MemTotal:16283212 kBMemFree:8985772 kBMemAvailable:11920424 kB…DirectMap4k:306976 kBDirectMap2M:9013248 kBDirectMap1G:8388608 kB

有问题的消息来自mm / page_alloc.c中的mem_init_print_info()函数(为清晰起见进行了编辑):pages_to_kb = PAGE_SHIFT-10; / * == 2 for 4KB x86 pages * / reserved_pa​​ges = get_num_physpages()-totalram_pages()…; pr_info(“内存:%luK /%luK可用(%luK内核代码,...,”“%luK保留,...)\ n“,nr_free_pages()> 10,…reserved_pa​​ges << pages_to_kb,…);

我不知道为什么这个内核突然认为我的nr_free_pages()比以前小得多,但是我期待发现。