MemAvailable
disertakan dalam /proc/meminfo
sejak versi 3.14 dari kernel; itu ditambahkan oleh komit 34e431b0a. Itulah faktor penentu dalam variasi keluaran yang Anda tampilkan. Pesan komit menunjukkan cara memperkirakan memori yang tersedia tanpa MemAvailable
:
Saat ini, jumlah memori yang tersedia untuk beban kerja baru, tanpa mendorong sistem ke swap, dapat diperkirakan dari
MemFree
,Active(file)
,Inactive(file)
, danSReclaimable
, serta tanda air "rendah" dari/proc/zoneinfo
.
Tanda air rendah adalah level di mana sistem akan bertukar. Jadi dengan tidak adanya MemAvailable
Anda setidaknya dapat menjumlahkan nilai yang diberikan untuk MemFree
, Active(file)
, Inactive(file)
dan SReclaimable
(mana saja yang ada di /proc/meminfo
), dan kurangi tanda air rendah dari /proc/zoneinfo
. Yang terakhir juga mencantumkan jumlah halaman gratis per zona, yang mungkin berguna sebagai perbandingan...
Algoritme lengkap diberikan dalam tambalan ke meminfo.c
dan tampaknya cukup mudah diadaptasi:
- jumlahkan tanda air rendah di semua zona;
- ambil memori kosong yang teridentifikasi (
MemFree
); - kurangi tanda air rendah (kita harus menghindari menyentuhnya untuk menghindari pertukaran);
- tambahkan jumlah memori yang dapat kita gunakan dari cache halaman (jumlah dari
Active(file)
danInactive(file)
):itulah jumlah memori yang digunakan oleh cache halaman, dikurangi setengah dari cache halaman, atau watermark rendah, mana saja yang lebih kecil; - tambahkan jumlah memori yang dapat kami klaim kembali (
SReclaimable
), mengikuti algoritme yang sama.
Jadi, menggabungkan semua ini, Anda bisa mendapatkan memori yang tersedia untuk proses baru dengan:
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
Sementara jawaban Stephen cukup sempurna dan keliru karena berhati-hati, saya memutuskan untuk menulis logika lengkap termasuk perbandingan minimum. Informasi pertama kali dibaca dari /proc/meminfo dan disimpan dalam variabel sehingga detail memori konsisten.
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
Hasil yang disimpan dalam variabel adalah dalam byte.