web-dev-qa-db-ja.com

ディストリビューション間で移植可能なメモリの量を取得するにはどうすればよいですか?

メモリをレポートする標準ファイル/ツールは、Linuxディストリビューションによってフォーマットが異なるようです。たとえば、ArchとUbuntuで。

  • アーチ

    $ free
                  total        used        free      shared  buff/cache   available
    Mem:        8169312     3870392     2648348       97884     1650572     4110336
    Swap:      16777212      389588    16387624
    
    
    $ head /proc/meminfo 
    MemTotal:        8169312 kB
    MemFree:         2625668 kB
    MemAvailable:    4088520 kB
    Buffers:          239688 kB
    Cached:          1224520 kB
    SwapCached:        17452 kB
    Active:          4074548 kB
    Inactive:        1035716 kB
    Active(anon):    3247948 kB
    Inactive(anon):   497684 kB
    
  • Ubuntu

    $ free
                 total       used       free     shared    buffers     cached
    Mem:      80642828   69076080   11566748    3063796     150688   58358264
    -/+ buffers/cache:   10567128   70075700
    Swap:     20971516    5828472   15143044
    
    
    $ head /proc/meminfo 
    MemTotal:       80642828 kB
    MemFree:        11565936 kB
    Buffers:          150688 kB
    Cached:         58358264 kB
    SwapCached:      2173912 kB
    Active:         27305364 kB
    Inactive:       40004480 kB
    Active(anon):    7584320 kB
    Inactive(anon):  4280400 kB
    Active(file):   19721044 kB
    

では、どのようにすれば(Linuxディストリビューション間のみ)移植性があり、ソフトウェアが特定の時間に使用できるメモリの量(スワップを除く)を確実に取得できますか?おそらく、Archのfreecat /proc/meminfoの出力で「利用可能」と「MemAvailable」と表示されるのはおそらくこれですが、Ubuntuまたは別のディストリビューションで同じようにするにはどうすればよいですか?

12
terdon

カーネルのバージョン3.14以降、MemAvailableは_/proc/meminfo_に含まれています。 commit 34e431b0a によって追加されました。これが、表示する出力変動の決定要因です。コミットメッセージは、MemAvailableなしで使用可能なメモリを推定する方法を示します。

現在、システムをスワップにプッシュせずに新しいワークロードに使用できるメモリの量は、MemFreeActive(file)Inactive(file)、およびSReclaimableだけでなく、 _/proc/zoneinfo_からの「低」透かし。

最低水準点は、システムがスワップするレベルです。したがって、MemAvailableがない場合は、少なくともMemFreeActive(file)Inactive(file)SReclaimable(_/proc/meminfo_に存在する方)に指定された値を合計して、 _/proc/zoneinfo_からの最低水準点。後者には、ゾーンごとの空きページ数も表示されます。これは、比較として役立つ場合があります...

完全なアルゴリズムは、_meminfo.c_へのパッチで提供されており、簡単に適応できます。

  • すべてのゾーンの最低水準点を合計します。
  • 識別された空きメモリ(MemFree)を取得します。
  • 最低水準点を差し引きます(スワップを回避するために、最低水準点に触れないようにする必要があります);
  • ページキャッシュから使用できるメモリの量を追加します(Active(file)Inactive(file)の合計):これは、ページキャッシュが使用するメモリの量から、ページキャッシュの半分を差し引いたものです。または最低水準点のどちらか小さい方。
  • 同じアルゴリズムに従って、再利用できるメモリ量(SReclaimable)を追加します。

したがって、これらすべてをまとめると、次のコマンドを使用して、新しいプロセスで使用できるメモリを取得できます。

_awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{print k}') \
 '{a[$1]=$2}
  END{ 
   print a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]-(12*low); 
  }' /proc/meminfo 
_
18
Stephen Kitt

スティーブンの答えは完全に十分であり、注意を怠りますが、私は最小限の比較を含む完全なロジックを書くことにしました。情報は最初に/ proc/meminfoから読み取られ、変数に格納されるため、メモリの詳細は一貫しています。

LOW_WATERMARK=$(awk '$1 == "low" {LOW_WATERMARK += $2} END {print LOW_WATERMARK * 4096}' /proc/zoneinfo)

MEMINFO=$(</proc/meminfo)

MEMINFO_MEMFREE=$(echo "${MEMINFO}" | awk '$1 == "MemFree:" {print $2 * 1024}')
MEMINFO_FILE=$(echo "${MEMINFO}" | awk '{MEMINFO[$1]=$2} END {print (MEMINFO["Active(file):"] + MEMINFO["Inactive(file):"]) * 1024}')
MEMINFO_SRECLAIMABLE=$(echo "${MEMINFO}" | awk '$1 == "SReclaimable:" {print $2 * 1024}')

MEMINFO_MEMAVAILABLE=$((
  MEMINFO_MEMFREE - LOW_WATERMARK
  + MEMINFO_FILE - ((MEMINFO_FILE/2) < LOW_WATERMARK ? (MEMINFO_FILE/2) : LOW_WATERMARK)
  + MEMINFO_SRECLAIMABLE - ((MEMINFO_SRECLAIMABLE/2) < LOW_WATERMARK ? (MEMINFO_SRECLAIMABLE/2) : LOW_WATERMARK)
))

if [[ "${MEMINFO_MEMAVAILABLE}" -le 0 ]]
then
  MEMINFO_MEMAVAILABLE=0
fi

変数に格納される結果はバイト単位です。

7
crashmaxed