CPU yang penuh hanya membuat proses mengantri; memori yang habis membuat kernel membunuh proses. Itulah sebabnya pemantauan memori punya urgensi berbeda: kehabisan RAM berujung pada OOM killer yang menghentikan layanan tanpa permisi, dan sering kali korban yang dipilih justru proses paling penting seperti database. Kabar baiknya, Linux tidak membiarkan RAM menganggur — sisa memori dipakai sebagai cache disk — sehingga membaca laporan memori butuh kebiasaan yang benar agar tidak panik terhadap angka yang kelihatannya buruk. Pada chapter ini kita bedah /proc/meminfo, membaca free dengan tepat, menemukan proses paling boros, lalu membangun laporan memori otomatis dengan awk.
/proc/meminfo: Sumber dari Semua Alat #
Semua alat pemantauan memori — free, top, htop — sebenarnya hanya memformat ulang satu file: /proc/meminfo. Kernel menulis statistik memori ke file ini dalam format Field: nilai kB yang sangat stabil, sehingga skrip kita bisa mengandalkannya. Field yang paling sering dibaca:
| Field | Arti |
|---|---|
MemTotal | total RAM fisik yang dikenal kernel |
MemFree | RAM yang benar-benar tidak dipakai apa pun |
MemAvailable | perkiraan RAM yang bisa dipakai proses baru tanpa menukar swap |
Buffers | cache metadata filesystem (superblock, direktori) |
Cached | cache isi file yang pernah dibaca dari disk |
SwapTotal, SwapFree | ukuran swap dan sisanya (dibedah di Chapter Swap Space ) |
Dua field pertama sering disalahartikan: MemFree rendah bukan berarti sistem bahaya. Isi Buffers dan Cached adalah salinan data disk yang sengaja ditahan di RAM supaya pembacaan berikutnya cepat — begitu aplikasi butuh memori, kernel melepas cache itu dalam hitungan detik. Karena itulah kernel sejak 2014 menyediakan MemAvailable: perkiraan memori yang benar-benar bisa dipakai, dihitung dari MemFree ditambah cache yang bisa direclaim. Pedoman praktisnya sederhana — pantau MemAvailable, bukan MemFree. Spesifikasi seluruh field ada di proc(5)
.
free -h dibedah #
Perintah free meringkas /proc/meminfo menjadi dua baris. Opsi -h membulatkan satuan agar mudah dibaca manusia, dan berikut contoh tampilan free -h pada mesin dengan RAM 16 GiB:
total used free shared buff/cache available
Mem: 15.5Gi 2.2Gi 7.8Gi 150Mi 5.5Gi 11.6Gi
Swap: 2.0Gi 0B 2.0GiBaris Mem punya enam kolom: total, used (dipakai proses), free (sungguhan kosong), shared (memori bersama seperti tmpfs), buff/cache (jumlah Buffers + Cached), dan available (padanan MemAvailable). Baris Swap melaporkan pemakaian ruang tukar di disk. Perhatikan ironi pada baris Mem: kolom free hanya 7.8 GiB dari 15.5 GiB, padahal kolom available menunjukkan 11.6 GiB — selisihnya adalah cache yang siap dilepas kapan saja.
Opsi lain yang berguna: free -m menampilkan angka dalam MiB (enak untuk skrip karena satuannya tetap), dan free -h -s 5 menyegarkan tampilan tiap 5 detik untuk mengamati tren singkat. Opsi lengkapnya ada di free(1)
.
Proses Paling Boros Memori #
Ketika available menipis, pertanyaan berikutnya adalah “siapa pelakunya?”. Perintah ps menjawabnya dengan mengurutkan berdasarkan kolom %MEM:
ps aux --sort=-%mem | head -6Berikut contoh tampilan hasilnya pada server aplikasi yang sedang memproses laporan besar:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 1121 1.2 18.4 4312100 2950000 ? Sl Mei01 120:15 /usr/sbin/mysqld
budi 2482 25.8 6.9 864312 1105210 ? Sl 14:02 3:11 chromium --type=renderer
budi 1902 4.1 3.2 512080 512340 ? Sl 13:58 0:41 code-server
www-data 990 0.8 1.9 210430 310200 ? S 09:00 1:03 /usr/sbin/nginxKolom %MEM adalah perbandingan RSS — resident set size, bagian memori proses yang benar-benar ditempati di RAM — terhadap total memori. Kolom VSZ jauh lebih besar karena menghitung seluruh ruang alamat yang dialokasikan, termasuk yang belum pernah disentuh; angka itu hampir tidak berguna untuk memperkirakan tekanan memori nyata. Urutan di atas menunjukkan mysqld menempati 18.4% RAM — kandidat pertama untuk diperiksa konfigurasinya (misalnya batas innodb_buffer_pool_size).
OOM Killer: Ketika Memori Benar-benar Habis #
Bila MemAvailable dan swap sama-sama habis, kernel masuk ke mode darurat: OOM (out of memory) killer menilai semua proses dengan skor “kejahatan” — ukuran memori, lama berjalan, prioritas — lalu membunuh skor tertinggi supaya sistem tetap hidup. Korban tidak bisa diprediksi dari luar: bisa jadi proses render video Budi, bisa jadi database utama. Jejaknya selalu tertinggal di log dengan pesan Out of memory: Killed process, dan kapan membaca jejak itu — beserta prosedur lengkap menangani kehabisan memori — kita bahas di Chapter Troubleshooting Performance
.
Latihan: Persentase Terpakai dari meminfo #
Sama seperti chapter sebelumnya, angka /proc/meminfo berbeda di setiap mesin dan berubah tiap detik, jadi latihan parsing kita kerjakan pada fixture statis yang formatnya sama persis dengan file asli. Nilai-nilainya sengaja konsisten dengan tampilan free -h di atas: MemTotal 16308124 kB adalah 15.5 GiB dan MemAvailable 12181000 kB adalah 11.6 GiB. Metrik yang dihitung: terpakai = MemTotal − MemAvailable, karena MemAvailable sudah memperhitungkan cache yang bisa direclaim:
cat > meminfo.txt <<'AKHIR'
MemTotal: 16308124 kB
MemFree: 8154032 kB
MemAvailable: 12181000 kB
Buffers: 213408 kB
Cached: 4012032 kB
SwapCached: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
AKHIR
awk '
/^MemTotal:/ { total = $2 }
/^MemAvailable:/ { avail = $2 }
END {
terpakai = total - avail
printf "RAM: %.1f GiB total | %.1f GiB terpakai | %.1f%%\n", \
total/1048576, terpakai/1048576, terpakai/total*100
}' meminfo.txtOutput yang Dihasilkan:
RAM: 15.6 GiB total | 3.9 GiB terpakai | 25.3%Bedah potongan awk di atas:
- Baris 13–14 (
/^MemTotal:/ ...): dua pola sederhana menangkap field yang dibutuhkan. Nilai berada di$2karena format file selaluNamaField: nilai kB— pola pemisahan field defaultawk(spasi berurutan) langsung memisahkannya. - Baris 15–19 (blok
END): perhitungan baru dijalankan setelah seluruh file terbaca.terpakai = total - availsengaja memakaiMemAvailable, bukanMemFree, agar cache yang bisa direclaim tidak dihitung sebagai beban. Pembagian1048576mengubah kB menjadi GiB, dan100membalik rasio menjadi persen. - Baris 17–18 (tanda
\): backslash di akhir baris melanjutkan perintahprintfke baris berikutnya — murni untuk keterbacaan, hasilnya sama dengan satu baris panjang.
Hasilnya membaca jujur: mesin ini baru memakai 25% kapasitas RAM-nya untuk proses, sisanya adalah ruang lega.
Skrip Laporan Memori #
Untuk pemantauan rutin, potongan di atas kita kemas menjadi skrip yang juga menilai swap dan memberi status. Dua fixture menguji dua keadaan: mesin sehat dan mesin yang sudah meminjam swap:
cat > meminfo.txt <<'AKHIR'
MemTotal: 16308124 kB
MemFree: 8154032 kB
MemAvailable: 12181000 kB
Buffers: 213408 kB
Cached: 4012032 kB
SwapCached: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
AKHIR
printf '%s\n' \
'MemTotal: 8123456 kB' \
'MemFree: 412000 kB' \
'MemAvailable: 730000 kB' \
'SwapTotal: 2097148 kB' \
'SwapFree: 1048574 kB' > meminfo-padat.txt
cat > laporan-memori.sh <<'SKRIP'
#!/bin/bash
# laporan-memori.sh <file-meminfo>
awk '
/^MemTotal:/ { total = $2 }
/^MemAvailable:/ { avail = $2 }
/^SwapTotal:/ { swap_total = $2 }
/^SwapFree:/ { swap_free = $2 }
END {
terpakai = total - avail
pct = terpakai / total * 100
printf "RAM : %6.1f GiB total | %6.1f GiB terpakai | %.1f%%\n", \
total/1048576, terpakai/1048576, pct
if (pct >= 90)
print "RAM : status KRITIS"
else if (pct >= 75)
print "RAM : status WASPADA"
else
print "RAM : status SEHAT"
swap_pakai = swap_total - swap_free
printf "Swap : %6.1f GiB total | %6.1f GiB terpakai\n", \
swap_total/1048576, swap_pakai/1048576
}' "$1"
SKRIP
bash laporan-memori.sh meminfo.txt
bash laporan-memori.sh meminfo-padat.txtOutput yang Dihasilkan:
RAM : 15.6 GiB total | 3.9 GiB terpakai | 25.3%
RAM : status SEHAT
Swap : 2.0 GiB total | 0.0 GiB terpakai
RAM : 7.7 GiB total | 7.1 GiB terpakai | 91.0%
RAM : status KRITIS
Swap : 2.0 GiB total | 1.0 GiB terpakaiBedah skrip di atas:
- Baris 12–17 (
printf '%s\n' ...): fixture kedua dibuat dengan satu perintahprintfyang menerima banyak argumen — format%s\ndiulang untuk tiap argumen sehingga tiap baris tercetak sendiri; alternatif ringkas untuk heredoc saat barisnya pendek-pendek. - Baris 19–42 (
laporan-memori.sh): pola/^Field:/tetap sama, hanya bertambahSwapTotaldanSwapFree. BlokENDkini mencetak laporan dua baris lalu menilai status lewat tanggaif— ambang 75% sebagai waspada dan 90% sebagai kritis. - Baris 44–45: dua fixture diuji. Mesin pertama sehat (25.3%). Mesin kedua memakai 91.0% RAM — status KRITIS — dan sudah meminjam 1.0 GiB swap; kombinasi yang lazim sebelum OOM killer ikut turun tangan.
Di mesin nyata, skrip ini bekerja langsung pada file asli: bash laporan-memori.sh /proc/meminfo. Teknik awk multi-baris yang dipakai di sini sudah kita latih di Chapter awk
. Setelah CPU dan memori, tinggal satu sumber daya yang paling sering membuat layanan berhenti mendadak: ruang disk yang habis — topik Chapter Disk Monitoring
.