メモリを報告する標準ファイル/ツールは、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ディストリビューションのみ)、確実に確保するにはどうすればよいですか?おそらくこれはfree
ArchとArchの出力に「Available」と「MemAvailable」と表示されますが、cat /proc/meminfo
Ubuntuや他のディストリビューションで同じ結果を得るにはどうすればよいですか?
答え1
MemAvailable
/proc/meminfo
カーネルバージョン3.14から含まれています。34e431b0a 提出。これが表示される出力変化の決定要因である。コミットメッセージは、次のことなく使用可能なメモリを推定する方法を示しますMemAvailable
。
現在のシステムをスワップにプッシュせずに新しいワークロードに使用できるメモリ量は、、、およびの
MemFree
「Active(file)
低」透かしに基づいて推定できます。Inactive(file)
SReclaimable
/proc/zoneinfo
低い透かしはシステム遷移レベルです。したがって、 がなければMemAvailable
、 、 と で提供される値の中にある値を加算し、その値から最低透かしを引くことができます。後者はまた、各領域に利用可能なページ数をリストするので、比較に役立つことがあります。MemFree
Active(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
変数に格納された結果はバイト単位です。