free(1)、/proc/meminfoとメモリの総容量

言われてみればそれはそうだなな言えるところで、free(1)とか/proc/meminfoにあるMemTotalが物理メモリの総容量ではないよねってのがありますね。

まずmanでfree(1) - Linux manual pageを見ると総容量なのかなと読める訳なんですね。

       total  Total installed memory (MemTotal and SwapTotal in
              /proc/meminfo)

でも、proc(5) - Linux manual pageでMemTotalの部分を読むと、使用可能なメモリ量とあります。例としてメモリの総容量 - (予約分 + カーネルバイナリコード)になるとあるのでfree(1)の説明とちょっと食い違いがあるんですね。

             MemTotal %lu
                     Total usable RAM (i.e., physical RAM minus a few
                     reserved bits and the kernel binary code).

そしてLinux 4.2のドキュメントDocumentation/filesystems/proc.txtを確認するとproc(5)の説明と同じなのがわかります。

844     MemTotal: Total usable ram (i.e. physical ram minus a few reserved
845               bits and the kernel binary code)
846      MemFree: The sum of LowFree+HighFree

ということで、free(1)の出力でtotalの部分はproc(5)の説明にある通りということでしょう。

x86/x86_64環境で実際の搭載量を確認するならdmidecodeコマンドを使うのが確実だと思います。

masami@saga:~$ sudo dmidecode -t memory | grep "Size:.*MB"
        Size: 8192 MB
        Size: 8192 MB
        Size: 8192 MB
        Size: 8192 MB

うちのデスクトップPCは8GBのメモリを4枚挿しているので正しく表示されています。

ただし、このコマンドはDMIテーブルからデータを読んでいるのでラズパイだと使えません。。

masami@mars:~$ sudo dmidecode -t memory
# dmidecode 3.0
Scanning /dev/mem for entry point.
# No SMBIOS nor DMI entry point found, sorry.

x86_64環境に戻ってdmesgでログを確認すると使用可能なメモリは33376068Kだけあって使えるのは32430260Kとでてます。ここの差分は945808K reservedと出ている部分です。

[    0.000000] Memory: 32430260K/33376068K available (5602K kernel code, 928K rwdata, 2580K rodata, 1852K init, 1164K bss, 945808K reserved, 0K cma-reserved)

この時点で32GiB(33554432KiB)から178364KiBほど減ってますね。カーネルのサイズとか1MiB以降のアドレスにカーネルを置いているとか色々な要素からでしょうか。

この後、いくつかfreeされて空き領域が増えます。

masami@saga:~$ dmesg | grep -i freeing
[    0.535350] Freeing SMP alternatives memory: 20K (ffffffff81cb9000 - ffffffff81cbe000)
[    2.501023] Freeing initrd memory: 3472K (ffff880074305000 - ffff880074669000)
[    2.571295] Freeing unused kernel memory: 1852K (ffffffff81aea000 - ffffffff81cb9000)
[    2.571860] Freeing unused kernel memory: 532K (ffff88000157b000 - ffff880001600000)
[    2.572340] Freeing unused kernel memory: 1516K (ffff880001885000 - ffff880001a00000)

最後にログインしてからfreeをするとこうなります。

masami@saga:~$ free -k
              total        used        free      shared  buff/cache   available
Mem:       32775276     5610992    25069072       77604     2095212    26751900
Swap:      62498812           0    62498812

dmesgで見た時は32430260Kだったのが、freeでは32775276Kになっているので345016Kほど増えています。dmesgで見た以上に増えた部分がどのへんなのかはこれだけだとわかりませんが/(^o^)\