Kafayı yemek üzereydim. Uzun zamandır sorunsuz çalışan Discord botum, bir anda "connection reset" vermeye başladı. Uzak sunucuya SSH bile atamadım. Meğerse o masum sandığım bot, gizli bir memory leak ile cihazın tüm RAM'ini ve swap alanını yutmuş, Raspberry Pi'imi tam bir tuğlaya çevirmiş. Şaka gibi!
Sistem Çöküşü ve Panik Anı
Her şey normal giderken, botun bulunduğu kanala komut attığımda yanıt gelmemeye başladı. "Belki ağ geçici kesilmiştir" deyip Discord Developer Portal'a baktım, bot çevrimiçi görünüyordu. Sonra pm2 logs ile loglara bakayım dedim, bağlantı yok. SSH denedim, Connection timed out. En sonunda monitöre fiş takıp direkt cihaza baktığımda gördüğüm manzara içler acısıydı: Terminal ekranı donmuş, hiçbir tuşa basılmıyordu. Gücü kesip açtığımda ise boot süresi yüzyıllar sürdü.
Sorunun Kökünü Kazımak
Sistem açılır açılmaz ilk iş htop'u açtım. Bot prosesi normal görünüyordu ama free -h komutunun çıktısı dehşeti gözler önüne serdi:
Swap tamamen dolmuştu! RAM de %99'u gösteriyordu. Demek ki bot, sürekli artan bir bellek kullanımına sebep oluyor ve sistem swap'a taşımak zorunda kalıyordu. Sonunda swap da dolunca, işletim sistemi çökme moduna geçmişti. Sorun, bot kodumda setInterval ile çalışan bir görevdeydi. Her döngüde yeni bir EventEmitter listener'ı ekliyor, ama eski listener'ları temizlemiyordum. Zamanla binlerce listener birikmiş, belleği tüketmişti.
Çözüm ve Alınan Ders
Kodu baştan aşağı memory leak açısından taradım. Özellikle event listener'lar, açık kalan database bağlantıları ve büyük array'lerin referanslarını kontrol ettim. Sorunlu fonksiyonu bulunca, her yeni listener'dan önce eskiyi .removeListener() ile temizledim. Ayrıca, node --inspect ile memory profili almayı ve pm2'ye restart politikası (max memory) eklemeyi de öğrendim.
Sonuç olarak, küçük ve "zararsız" sandığımız projeler bile, dikkatsiz bir kod parçasıyla fiziksel donanımı kilitleyebiliyor. Özellikle Raspberry Pi gibi kaynakları kısıtlı cihazlarda, memory management'a ekstra özen göstermek şart.
Siz de benzer bir "bellek canavarı" yarattınız mı? Özellikle Node.js'de memory leak'leri takip etmek için favori araç veya metodunuz var mı?
Her şey normal giderken, botun bulunduğu kanala komut attığımda yanıt gelmemeye başladı. "Belki ağ geçici kesilmiştir" deyip Discord Developer Portal'a baktım, bot çevrimiçi görünüyordu. Sonra pm2 logs ile loglara bakayım dedim, bağlantı yok. SSH denedim, Connection timed out. En sonunda monitöre fiş takıp direkt cihaza baktığımda gördüğüm manzara içler acısıydı: Terminal ekranı donmuş, hiçbir tuşa basılmıyordu. Gücü kesip açtığımda ise boot süresi yüzyıllar sürdü.
Sistem açılır açılmaz ilk iş htop'u açtım. Bot prosesi normal görünüyordu ama free -h komutunun çıktısı dehşeti gözler önüne serdi:
Bash:
Swap: 1.0G used, 0B free
Swap tamamen dolmuştu! RAM de %99'u gösteriyordu. Demek ki bot, sürekli artan bir bellek kullanımına sebep oluyor ve sistem swap'a taşımak zorunda kalıyordu. Sonunda swap da dolunca, işletim sistemi çökme moduna geçmişti. Sorun, bot kodumda setInterval ile çalışan bir görevdeydi. Her döngüde yeni bir EventEmitter listener'ı ekliyor, ama eski listener'ları temizlemiyordum. Zamanla binlerce listener birikmiş, belleği tüketmişti.
Kodu baştan aşağı memory leak açısından taradım. Özellikle event listener'lar, açık kalan database bağlantıları ve büyük array'lerin referanslarını kontrol ettim. Sorunlu fonksiyonu bulunca, her yeni listener'dan önce eskiyi .removeListener() ile temizledim. Ayrıca, node --inspect ile memory profili almayı ve pm2'ye restart politikası (max memory) eklemeyi de öğrendim.
Sonuç olarak, küçük ve "zararsız" sandığımız projeler bile, dikkatsiz bir kod parçasıyla fiziksel donanımı kilitleyebiliyor. Özellikle Raspberry Pi gibi kaynakları kısıtlı cihazlarda, memory management'a ekstra özen göstermek şart.
Siz de benzer bir "bellek canavarı" yarattınız mı? Özellikle Node.js'de memory leak'leri takip etmek için favori araç veya metodunuz var mı?