Bellek Sızıntısı Tespiti ve Çözümü
Linux sunucuda bellek sızıntısı (memory leak) tespiti, hangi sürecin bellek tükettiğini bulma ve çözüm yöntemleri.
İçindekiler
Giriş
Bellek sızıntısı, bir uygulamanın kullandığı belleği düzgün şekilde serbest bırakmaması sonucu RAM kullanımının zamanla sürekli artmasıdır. Sonunda sistem belleği tükenir, swap alanı dolmaya başlar ve sunucu yavaşlar veya çöker. Bu rehberde bellek sızıntısını tespit etme ve çözme yöntemlerini ele alacağız.
Belirtiler
Bellek sızıntısının tipik belirtileri:
- RAM kullanımı zamanla sürekli artıyor (yeniden başlatmadan sonra normale dönüyor)
free -hçıktısında kullanılabilir bellek giderek azalıyor- Swap kullanımı artıyor
- Uygulama zamanla yavaşlıyor
- OOM (Out of Memory) killer devreye giriyor ve süreçler öldürülüyor
dmesg'deoom-killmesajları görünüyor
Adım 1: Mevcut Bellek Durumunu Kontrol Et
# Genel bellek durumu
free -h
# Detaylı bellek bilgisi
cat /proc/meminfo
# Swap kullanımı
swapon --show
# OOM killer logları
dmesg | grep -i 'oom\|killed process\|out of memory'
journalctl -k | grep -i 'oom\|killed'
free -h çıktısında available değeri toplam RAM'in %10'unun altına düştüyse bellek baskısı var demektir.
Adım 2: Hangi Süreç En Çok Bellek Kullanıyor?
# ps ile bellek kullanımına göre sıralama
ps aux --sort=-%mem | head -20
# top ile gerçek zamanlı izleme
top
# 'M' tuşuna basarak belleğe göre sırala
# smem ile daha detaylı bellek analizi
sudo apt install smem -y
smem -r -k | head -20
# Süreç bazlı bellek kullanımı
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -20
# Belirli bir sürecin bellek kullanımını izle
watch -n 2 'ps aux | grep uygulama_adi | grep -v grep'
Adım 3: Bellek Sızıntısını Doğrula
Bir sürecin gerçekten bellek sızdırıp sızdırmadığını doğrulamak için zaman içindeki değişimi izleyin:
# Belirli bir sürecin PID'ini bul
pgrep -f uygulama_adi
# Sürecin bellek kullanımını her 30 saniyede bir kaydet
while true; do
echo "$(date): $(cat /proc/PID/status | grep VmRSS)"
sleep 30
done
# /proc/PID/smaps ile detaylı bellek haritası
cat /proc/PID/smaps | grep -E '(Rss|Pss|Shared|Private)' | awk '{sum += $2} END {print sum/1024 " MB"}'
# Sürecin bellek büyümesini izle
pidstat -r -p PID 10
Adım 4: Sistem Genelinde Bellek Analizi
# Slab cache kullanımı (kernel bellek sızıntısı)
cat /proc/slabinfo | sort -k3 -rn | head -20
slabtop
# Büyük bellek tüketen süreçler (smaps)
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
rss=$(cat /proc/$pid/smaps 2>/dev/null | grep Rss | awk '{sum+=$2} END {print sum}')
if [ ! -z "$rss" ] && [ "$rss" -gt 100000 ]; then
echo "PID $pid: $((rss/1024)) MB - $(cat /proc/$pid/comm 2>/dev/null)"
fi
done 2>/dev/null | sort -t: -k2 -rn | head -10
# Anonim bellek kullanımı
grep -E '(AnonPages|Mapped|Shmem)' /proc/meminfo
Adım 5: Uygulama Bazlı Çözümler
Node.js Bellek Sızıntısı
# Node.js heap dump al
kill -USR2 PID # heapdump modülü gerektirir
# Node.js bellek limitini ayarla
node --max-old-space-size=512 app.js
# PM2 ile otomatik yeniden başlatma (bellek limiti)
pm2 start app.js --max-memory-restart 500M
PHP-FPM Bellek Sızıntısı
# /etc/php/8.x/fpm/pool.d/www.conf
# pm.max_requests = 500 # Her worker 500 istek sonrası yeniden başlar
# PHP bellek limiti
# memory_limit = 256M
MySQL/MariaDB Bellek Kullanımı
# MySQL bellek kullanımını kontrol et
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
mysql -e "SHOW STATUS LIKE 'Innodb_buffer_pool_pages%';"
# /etc/mysql/mysql.conf.d/mysqld.cnf
# innodb_buffer_pool_size = 256M # RAM'in %25-50'si
# query_cache_size = 0 # MySQL 8'de kaldırıldı
Java Bellek Sızıntısı
# JVM heap dump
jmap -dump:format=b,file=/tmp/heap.hprof PID
# JVM bellek istatistikleri
jstat -gcutil PID 1000 10
# JVM heap boyutunu sınırla
java -Xmx512m -Xms256m -jar app.jar
Adım 6: Acil Çözümler
Bellek Önbelleğini Temizle
# Sayfa önbelleğini temizle (güvenli)
sync && echo 1 > /proc/sys/vm/drop_caches
# Dentry ve inode önbelleğini temizle
sync && echo 2 > /proc/sys/vm/drop_caches
# Tüm önbellekleri temizle (dikkatli kullanın)
sync && echo 3 > /proc/sys/vm/drop_caches
drop_caches komutu üretim ortamında dikkatli kullanılmalıdır. Önbellek temizlendikten sonra disk I/O geçici olarak artabilir.
Sızdıran Süreci Yeniden Başlat
# Servisi yeniden başlat
sudo systemctl restart servis_adi
# Belirli bir süreci öldür ve yeniden başlat
sudo kill -9 PID
# Otomatik yeniden başlatma için systemd ayarı
# /etc/systemd/system/servis.service
# [Service]
# Restart=always
# RestartSec=5
# MemoryMax=512M # Bellek limiti
Swap Alanını Artır
# Geçici swap dosyası oluştur
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# Kalıcı hale getir (/etc/fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Adım 7: Uzun Vadeli Çözümler
# systemd ile bellek limiti uygula
# /etc/systemd/system/servis.service
# [Service]
# MemoryMax=1G
# MemoryHigh=800M
# cgroup ile bellek limiti
cgcreate -g memory:myapp
echo 536870912 > /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes
cgexec -g memory:myapp uygulama
# Düzenli yeniden başlatma (geçici çözüm)
# crontab -e
# 0 4 * * * systemctl restart sızdıran_servis
Sonuç
Bellek sızıntısı sorunlarını çözmek için önce ps aux ve smem ile hangi sürecin bellek tükettiğini tespit edin, ardından zaman içindeki büyümeyi izleyerek sızıntıyı doğrulayın. Kısa vadede sızdıran servisi yeniden başlatın ve systemd ile bellek limiti uygulayın. Uzun vadede uygulamanın kaynak kodunu inceleyerek sızıntının kaynağını bulun. Sorun devam ederse REXE destek ile iletişime geçin.
İlgili Makaleler
SSH Bağlantı Sorunu: Sunucuya Bağlanamıyorum
SSH bağlantı sorunlarını çözme rehberi: Path.net firewall kuralları, Default Block, SSH portu için filtre kuralı oluşturma ve sorun giderme adımları.
RDP Bağlantı Sorunu: Windows Sunucuya Erişilemiyor
RDP bağlantı sorunlarını çözme rehberi: Path.net firewall kuralları, Default Block, RDP portu için filtre kuralı oluşturma ve sorun giderme adımları.
MTR Testi Nasıl Yapılır ve Destek Ekibine Gönderilir
WinMTR ve Linux MTR ile ağ testi yapma, ICMP filtre kuralı oluşturma ve sonuçları destek ekibine gönderme rehberi. Paket kaybı ve gecikme analizi.