Linux’ta Bellek Kullanımını Anlama: free, vmstat ve /proc/meminfo

Sunucunuzda bir performans sorunu var ve ilk içgüdünüz “acaba bellek mi doldu?” oluyor. Haklısınız, çünkü bellek sorunları sistem yavaşlamalarının en yaygın nedenlerinden biri. Ama free -h çıktısına bakıp “tamam, bellek var” deyip geçmek sizi yanıltabilir. Linux bellek yönetimi göründüğünden çok daha karmaşık ve nüanslı bir yapıya sahip. Bu yazıda free, vmstat ve /proc/meminfo araçlarını derinlemesine inceleyeceğiz, çıktıları gerçekten nasıl okuyacağınızı öğreneceğiz ve gerçek dünya senaryolarında bu bilgileri nasıl kullanacağınızı göreceğiz.

Linux Bellek Yönetimini Anlamak: Temel Kavramlar

Araçlara geçmeden önce birkaç temel kavramı netleştirmek gerekiyor, çünkü bu kavramları bilmeden çıktıları yorumlamak neredeyse imkansız.

Page Cache: Linux, disk I/O performansını artırmak için okunan dosyaları belleğe cache’ler. Bu cache “boş” bellek gibi görünmez ama ihtiyaç duyulduğunda anında geri alınabilir. Yani “kullanılmış” görünen belleğin büyük kısmı aslında geri alınabilir cache olabilir.

Swap: Fiziksel RAM dolduğunda kernel, az kullanılan bellek sayfalarını diske taşır. Swap kullanımı kötü bir şey değildir, ama yoğun swap aktivitesi (thrashing) ciddi performans sorunlarına yol açar.

Buffer vs Cache: Eski Linux versiyonlarında buffers (blok cihaz tamponu) ve cache (dosya sistemi cache’i) ayrı kategorilerdi. Modern sistemlerde ikisi buff/cache olarak birleştirilmiştir.

OOM Killer: Bellek tamamen tükendiğinde Linux’un OOM (Out of Memory) Killer’ı devreye girer ve bazı süreçleri öldürür. Bu duruma düşmemek için erken uyarı sistemleri kurmak şart.

free Komutu: Hızlı Genel Bakış

free komutu bellek durumuna hızlı bir bakış atmanın en kolay yolu. Ama çıktıyı doğru okumak önemli.

free -h

Tipik bir çıktı şöyle görünür:

              total        used        free      shared  buff/cache   available
Mem:           15Gi        8.2Gi       1.1Gi       542Mi       5.9Gi       6.8Gi
Swap:         2.0Gi        234Mi       1.8Gi

Buradaki en kritik sütun available‘dır. Çoğu sysadmin yeni başladığında free sütununa bakıp “sadece 1.1 GB boş var, bellek dolmak üzere!” diye panik yapar. Oysa available sütunu 6.8 GB gösteriyor. Bu, swap’a gitmeden yeni süreçlere tahsis edilebilecek gerçek bellek miktarıdır.

free komutunun kullanışlı parametreleri:

  • -h: İnsan okunabilir format (GB, MB cinsinden)
  • -m: Megabyte cinsinden göster
  • -g: Gigabyte cinsinden göster
  • -s [saniye]: Belirtilen aralıklarla sürekli güncelle
  • -c [sayı]: Kaç kez çalıştırılacağını belirle
  • -w: Wide mode, buffers ve cache’i ayrı göster

Belleği her 2 saniyede bir, 5 kez izlemek için:

free -h -s 2 -c 5

-w parametresi özellikle eski alışkanlıkları olan sysadminler için faydalı:

free -hw
              total        used        free      shared     buffers       cache   available
Mem:           15Gi        8.2Gi       1.1Gi       542Mi       312Mi       5.6Gi       6.8Gi
Swap:         2.0Gi        234Mi       1.8Gi

Swap Kullanımını Değerlendirmek

Swap sütununa bakarken dikkat etmeniz gereken şey kullanım miktarından çok değişim hızıdır. 234 MB swap kullanımı tek başına kötü değil, ama bu rakam her dakika artıyorsa problem var demektir.

# Swap kullanımını 5 saniye aralıklarla izle
watch -n 5 'free -h'

vmstat: Dinamik Sistem İstatistikleri

vmstat (virtual memory statistics) çok daha zengin bilgi sunar ve özellikle dinamik analiz için güçlüdür. Tek seferlik çıktıdan çok periyodik izleme modunda kullanıldığında gerçek değerini gösterir.

# 2 saniye aralıklarla, 10 satır çıktı al
vmstat 2 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0 239616 1124352 319488 5832704    0    1    45    23  312  687  8  2 89  1  0
 2  0 239616 1098752 319488 5845248    0    0     0   124  445  923 12  3 84  1  0
 0  0 239616 1134592 319488 5845248    0    0     0    36  289  634  5  1 93  1  0

Bu çıktı ilk bakışta korkutucu görünebilir. Sütunları anlayalım:

procs bölümü:

  • r: Run queue’da bekleyen süreç sayısı (CPU için bekleyenler)
  • b: Uninterruptible sleep’teki süreç sayısı (genellikle I/O bekliyor)

memory bölümü:

  • swpd: Kullanılan swap miktarı (KB)
  • free: Boş bellek (KB)
  • buff: Buffer’larda kullanılan bellek
  • cache: Cache’de kullanılan bellek

swap bölümü (kritik!):

  • si: Swap’tan okunan veri (swap in, KB/s)
  • so: Swap’a yazılan veri (swap out, KB/s)

io bölümü:

  • bi: Blok cihazdan okunan blok sayısı
  • bo: Blok cihaza yazılan blok sayısı

system bölümü:

  • in: Saniyedeki interrupt sayısı
  • cs: Saniyedeki context switch sayısı

cpu bölümü:

  • us: User space CPU kullanımı (%)
  • sy: Kernel space CPU kullanımı (%)
  • id: Boşta geçen süre (%)
  • wa: I/O bekleme süresi (%)
  • st: Sanal makinelerde çalınan CPU süresi

vmstat ile Sorun Tespiti

Gerçek bir senaryo düşünelim: Sabah 9’da uygulamanız yavaşlamaya başladı.

vmstat 1 30

Çıktıda şunu görüyorsunuz:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  2 1842176  45312  12288 892416  245  312  1823   456 2341 4521 45 12 15 28  0
 6  3 1953664  38912  12288 887808  312  445  2134   534 2891 5234 52 15  8 25  0
 8  4 2045952  32768  12288 881664  389  512  2456   612 3234 6123 58 18  4 20  0

Bu çıktı bir felaketi gösteriyor: si ve so değerleri yüksek ve artıyor (aktif swap thrashing), free azalıyor, r değeri yüksek (CPU bekleyen süreçler), wa değeri yüksek (I/O beklemesi), b değeri yüksek (I/O’da bloke olan süreçler). Sistem bellek baskısı altında ve sürekli swap yapıyor.

vmstat ile Bellek İstatistikleri

Bellek detayları için -s parametresi çok kullanışlı:

vmstat -s
     16384000 K total memory
      8601600 K used memory
      7823872 K active memory
      4234240 K inactive memory
      1126400 K free memory
       319488 K buffer memory
      5832704 K swap cache
      2097148 K total swap
       239616 K used swap
      1857532 K free swap

Burada active ve inactive ayrımı önemlidir. Active bellek yakın zamanda kullanılmış sayfalardır. Inactive bellek ise uzun süredir erişilmemiş, gerektiğinde geri alınabilir sayfalardır.

/proc/meminfo: Ham Veri Kaynağı

/proc/meminfo Linux’un bellek alt sisteminin ham veri deposudur. free ve vmstat aslında bu dosyadan okuyarak çalışır. Tam resmi görmek için doğrudan bu dosyaya bakmak gerekir.

cat /proc/meminfo
MemTotal:       16777216 kB
MemFree:         1126400 kB
MemAvailable:    6963200 kB
Buffers:          319488 kB
Cached:          5713920 kB
SwapCached:        45056 kB
Active:          7823872 kB
Inactive:        4234240 kB
Active(anon):    4521984 kB
Inactive(anon):  1892352 kB
Active(file):    3301888 kB
Inactive(file):  2341888 kB
Unevictable:       65536 kB
Mlocked:           65536 kB
SwapTotal:       2097148 kB
SwapFree:        1857532 kB
Dirty:             12288 kB
Writeback:             0 kB
AnonPages:       6369280 kB
Mapped:           892928 kB
Shmem:            555008 kB
KReclaimable:     456704 kB
Slab:             892928 kB
SReclaimable:     456704 kB
SUnreclaim:       436224 kB
KernelStack:       32768 kB
PageTables:        65536 kB
CommitLimit:    10485756 kB
Committed_AS:   12345344 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      131072 kB
HugePages_Total:       0
HugePages_Free:        0

Önemli alanları açıklayalım:

  • MemTotal: Sistemdeki toplam kullanılabilir RAM (kernel tarafından ayrılan kısım dahil değil)
  • MemFree: Tamamen boş, hiç kullanılmamış bellek
  • MemAvailable: Swap’a gitmeden tahsis edilebilecek bellek (bu değer en önemlisi)
  • Buffers: Blok cihaz tamponu
  • Cached: Dosya sistemi cache’i
  • SwapCached: Hem RAM’de hem swap’ta olan sayfalar
  • Active(anon): Anonim aktif sayfalar (heap, stack)
  • Inactive(anon): Anonim inaktif sayfalar (swap adayı)
  • Active(file): Dosya cache’inden aktif sayfalar
  • Inactive(file): Dosya cache’inden inaktif sayfalar (geri alınabilir)
  • Dirty: Diske yazılmayı bekleyen değiştirilmiş sayfalar
  • Slab: Kernel veri yapıları için kullanılan bellek
  • SReclaimable: Geri alınabilir slab belleği
  • SUnreclaim: Geri alınamaz slab belleği
  • CommitLimit: Overcommit sınırı
  • Committed_AS: Taahhüt edilmiş toplam bellek

Committed_AS vs CommitLimit

Bu iki değer kritik öneme sahip. Eğer Committed_AS değeri CommitLimit‘i aşıyorsa, sistem tehlikeli bölgede demektir. Overcommit aktifse kernel işlemlerin tüm talep ettiği belleği gerçekten vermez, ama yine de izlemek gerekir.

# Overcommit durumunu kontrol et
cat /proc/sys/vm/overcommit_memory
cat /proc/sys/vm/overcommit_ratio

/proc/meminfo ile Özel Sorgular

Belirli değerleri hızlıca çekmek için grep kullanabilirsiniz:

# Sadece kritik değerleri göster
grep -E "MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree|Dirty|Slab" /proc/meminfo
# Bellek kullanım yüzdesini hesapla (bash ile)
awk '/MemTotal/{total=$2} /MemAvailable/{avail=$2} END{printf "Kullanim: %.1f%%n", (1-avail/total)*100}' /proc/meminfo

Gerçek Dünya Senaryoları

Senaryo 1: Web Sunucusunda Yavaşlama

Bir e-ticaret sitesinde trafik artışı sırasında yavaşlama şikayeti var. Önce genel duruma bakıyoruz:

free -h && echo "---" && vmstat 1 5

free çıktısı normal görünüyor ama vmstat çıktısında wa (I/O wait) %35 civarında. /proc/meminfo‘ya bakıyoruz:

grep -E "Dirty|Writeback|SwapCached" /proc/meminfo
Dirty:            892928 kB
Writeback:         45056 kB
SwapCached:       123904 kB

Dirty bellek çok yüksek (neredeyse 900 MB). Yazma işlemleri birikmiş. Bu durumda vm.dirty_ratio ve vm.dirty_background_ratio parametrelerini kontrol etmek gerekir:

sysctl vm.dirty_ratio vm.dirty_background_ratio vm.dirty_writeback_centisecs

Senaryo 2: Java Uygulamasında Bellek Sızıntısı

Java uygulaması çalışırken bellek kullanımının sürekli arttığı şüphesi var. Saatlik olarak belleği loglayabiliriz:

# Her saat başı bellek durumunu logla
while true; do
    echo "$(date): $(grep MemAvailable /proc/meminfo)" >> /var/log/memwatch.log
    sleep 3600
done

Daha pratik bir yöntem:

# Belirli bir süreç için bellek kullanımını izle
PID=$(pgrep -f "java -jar myapp")
while true; do
    echo "$(date) - RSS: $(awk '/VmRSS/{print $2}' /proc/$PID/status) kB"
    sleep 60
done

Senaryo 3: Slab Belleği Şişmesi

Bazen free normal görünür ama sistem yavaştır. Slab belleğini kontrol edin:

cat /proc/slabinfo | sort -k3 -n -r | head -20

Ya da daha okunabilir:

slabtop -s c

Eğer dentry veya inode_cache slab değerleri çok büyükse, büyük miktarda dosya sistemi operasyonu yaşanmış ve cache şişmiş olabilir. Bu durumda:

# Slab cache'i temizle (dikkatli kullanın, production'da performansı geçici olarak düşürebilir)
echo 2 > /proc/sys/vm/drop_caches

Senaryo 4: OOM Killer Devreye Girdi mi?

# OOM killer log kontrolü
grep -i "oom|killed process" /var/log/syslog | tail -20
# ya da
dmesg | grep -i "oom|out of memory|killed process" | tail -20

OOM killer bir süreci öldürdüyse, hangi süreçlerin en fazla bellek tükettiğini anlamak için:

# Süreçleri bellek kullanımına göre sırala
ps aux --sort=-%mem | head -15

Bellek İzleme Script’i

Tüm bu bilgileri bir araya getiren pratik bir izleme script’i:

#!/bin/bash
# mem_report.sh - Detayli bellek raporu

echo "=== BELLEK DURUMU RAPORU ==="
echo "Tarih: $(date)"
echo ""

# Genel bellek durumu
echo "--- Genel Durum ---"
free -h
echo ""

# Kritik /proc/meminfo degerleri
echo "--- Kritik Degerler ---"
awk '
/MemTotal/{printf "Toplam RAM:     %s kBn", $2}
/MemAvailable/{printf "Kullanilabilir: %s kBn", $2}
/SwapTotal/{stotal=$2}
/SwapFree/{sfree=$2; printf "Swap Kullanimi: %s kB / %s kBn", stotal-sfree, stotal}
/Dirty/{printf "Dirty Pages:    %s kBn", $2}
/SUnreclaim/{printf "Slab (geri alinamaz): %s kBn", $2}
/Committed_AS/{cas=$2}
/CommitLimit/{climit=$2; printf "Commit: %s kB / %s kB (%%%s)n", cas, climit, int(cas/climit*100)}
' /proc/meminfo
echo ""

# En fazla bellek kullanan 5 surec
echo "--- En Fazla Bellek Kullanan Surecler ---"
ps aux --sort=-%mem | awk 'NR<=6{printf "%-20s %6s%% %10s kBn", $11, $4, $6}'
echo ""

# Kisa vmstat ozeti
echo "--- Son 5 Saniye vmstat ---"
vmstat 1 5

Bu script’i crontab’a ekleyerek düzenli raporlama yapabilirsiniz:

# Her saat basina calistir ve logla
0 * * * * /usr/local/bin/mem_report.sh >> /var/log/mem_hourly.log 2>&1

Bellek Performansı için Pratik Öneriler

/proc/sys/vm/ altındaki parametreler bellek yönetimini etkiler. En önemlileri:

  • vm.swappiness: 0-100 arası değer. Düşük değer swap kullanımını azaltır. Masaüstü için 10, sunucu için 20-30 önerilir. Veritabanı sunucuları için 1-10 denenebilir.
  • vm.dirty_ratio: Dirty page’lerin RAM’e oranı bu değeri aşınca sync başlar. Varsayılan 20.
  • vm.dirty_background_ratio: Arka planda yazma işleminin başladığı oran. Varsayılan 10.
  • vm.vfs_cache_pressure: Kernel’in dosya sistemi cache’ini ne kadar agresif geri alacağı. Varsayılan 100.
# Swappiness degerini kalici olarak ayarla
echo "vm.swappiness=20" >> /etc/sysctl.conf
sysctl -p

Sonuç

Linux bellek yönetimi ilk başta kafa karıştırıcı gelebilir, özellikle “kullanılmış görünen” belleğin aslında geri alınabilir cache olduğunu anlayana kadar. Bu yazıda ele aldığımız üç araç birbirini tamamlar niteliktedir.

free -h ile günlük hızlı kontrol yapın, ama available sütununa odaklanın, free sütununa değil. vmstat 2 10 ile dinamik durumu izleyin; özellikle si/so (swap aktivitesi) ve wa (I/O bekleme) değerlerine dikkat edin. /proc/meminfo ise gerçek anlamda derinlemesine analiz için başvuracağınız kaynak. Slab şişmesi, overcommit durumu, dirty page birikimi gibi sorunları burada görebilirsiniz.

Bir performans sorunu yaşadığınızda paniklemeden önce bu üç araçla sistematik bir analiz yapın. Çoğu zaman sorunun kaynağı ham bellek eksikliği değil, yanlış yapılandırılmış swap politikası, şişmiş slab cache veya I/O darboğazı olduğunu göreceksiniz. Bu araçları düzenli kullanmak ve baseline değerleri bilmek, sorun anında ne kadar sapma olduğunu anlamanızı da sağlar. Sonuçta iyi bir sysadmin sorun çıktıktan sonra değil, çıkmadan önce müdahale edendir.

Yorum yapın