ディストリビューションで移植可能な使用可能なメモリ量を取得するには?

ディストリビューションで移植可能な使用可能なメモリ量を取得するには?

メモリを報告する標準ファイル/ツールは、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ディストリビューションのみ)、確実に確保するにはどうすればよいですか?おそらくこれはfreeArchとArchの出力に「Available」と「MemAvailable」と表示されますが、cat /proc/meminfoUbuntuや他のディストリビューションで同じ結果を得るにはどうすればよいですか?

答え1

MemAvailable/proc/meminfoカーネルバージョン3.14から含まれています。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 

答え2

Stephenの答えは非常に適切で注意が不足していますが、最小限の比較を含むロジック全体を記録することにしました。情報はまず/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

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

関連情報