sysctlの「メモリ不足」の説明

sysctlの「メモリ不足」の説明

OS X Yosemiteで次のコードを実行しました。

unsigned long num_;
sysctl((int[]){CTL_HW, HW_PHYSMEM}, 2, &num_, &len, NULL, 0);
printf("AMT MEM: , %lu\n", num_);

そして戻ってきて140735340871680

これは言葉ではありません:(IPython 3で)

In [3]: mem / (1024 ** 3)
mem / (1024 ** 3)
Out[3]: 131070.0

16GBの物理メモリがあるからです。タイトルを見sysctl.hました。

#define HW_PHYSMEM   5      /* int: total memory */
#define HW_USERMEM   6      /* int: non-kernel memory */

今これは本当に言葉ではありません。合格すると、数字は信頼できますが、HW_USERMEM具体的には合計メモリを要求しました。何を提供しますか?

私はPythonコードで愚かな数学ミスを犯しましたか?

答え1

私はPythonコードで愚かな数学ミスを犯しましたか?

実際に間違っているのはCコードです。

コードの最も簡単な修正は次のとおりです。

#include <stdio.h>
#include <sys/sysctl.h>

int main(void)
{
    int64_t bytes;
    size_t len = sizeof(bytes);
    sysctl({ CTL_HW, HW_PHYSMEM64 }, 2, &bytes, &len, NULL, 0);
    int megs = bytes / 1024 / 1024;
    printf("AMT MEM: %d MiB\n", megs);
}

代わりにそれを使用すると、HW_PHYSMEMバイト数は32ビットサイズと見なされる変数に格納されるため、RAMが最大2GiBのシステムでのみ機能します。 64ビットパラメータを変更するには、sysctl以前のバージョンとの互換性が壊れるのを防ぐために新しい値が必要です。これがOpenBSDのsysctl(3)マニュアルページでHW_PHYSMEM使用されなくなったことを示している理由です。

上記のコードをいくつか変更しました。私は計算機を介して入力しなくても出力を読み取ることができるように、Cコードでいくつかの数学的な作業を行っています。また、わかりやすくするnum_ために、いくつかの整数型警告を修正し、変数名を変更しましたbytes

このコードは一部のBSDでは正しく実行されますが、OS XまたはFreeBSDでは動作しません。

OS Xのマニュアルページを見ると、彼らはあなたが使用したいようです。sysctlbyname(3)代わりに。ヨセミテではうまくいきます。

#include <stdio.h>
#include <sys/sysctl.h>

int main(void)
{
    int64_t bytes;
    size_t len = sizeof(bytes);
    sysctlbyname("hw.memsize", &bytes, &len, NULL, 0);
    int megs = bytes / 1024 / 1024;
    printf("AMT MEM: %d MiB\n", megs);
}

16GiBの物理RAMがあり、16384MiBが正しく報告されます。

しかし、FreeBSDでこれを試してみると、答えは0になります。少し掘り下げると、hw.physmemその逆を望むことがわかります。

もう一度我々は壁にぶつかった。それ sysctlbynameOS Xの値は、あなたが見つけた一種の偽の結果を提供します。

したがって、結論として、これらすべてはシステムによって非常に異なるということです。クロスプラットフォームが必要な場合はたくさん#ifdefs


脚注:

  1. 申し訳ありません。まだ2の累乗を10億に少なくありません。 :)

  2. OpenBSD 5.5 および NetBSD 6.0.1 でテストされました。

関連情報