JavaScript Heap Out of Memory Hatası Nasıl Çözülür? Node.js

JavaScript heap out of memory hatası nedir ve hemen ne yapmalıyım?
JavaScript heap out of memory, Node.js sürecinin V8 motorunun ayırdığı yığın (heap) belleğini doldurduğunu ve çöp toplayıcının yer açamadığını söyleyen ölümcül bir hatadır. Hemen yapacağınız şey, sürecin bellek sınırını geçici olarak yükseltmek ve ardından belleği asıl tüketen işi bulmaktır.
Panik yapmayın, çünkü bu hata çoğu zaman tek bir satırlık bir ayarla geçici olarak aşılır. Ancak kalıcı çözüm farklı bir yerde yatar. Önce hızlı adımlara, sonra nedenlere bakacağız.
- Hatayı üreten komutu not edin (derleme mi, sunucu mu, betik mi).
- Sınırı geçici olarak yükseltin:
node --max-old-space-size=4096 uygulama.js(değer yalnızca örnektir). - Aynı komutu çalıştırın ve hatanın kaybolup kaybolmadığına bakın.
- Hata geri geliyorsa bellek sızıntısından ya da büyük veriden şüphelenin.
- Bu yazıdaki teşhis sırasını izleyin ve kalıcı önlemi uygulayın.
Adımlar sahada gördüğümüz teşhis sırasıdır. Bu nedenle en olası nedenden en az olasıya doğru ilerleyeceğiz.
Node.js bu hatayı tam olarak neden veriyor?
Node.js, JavaScript'i V8 motoruyla çalıştırır. V8, nesneleri yığın adı verilen bir bellek bölgesinde tutar. Bu bölgenin bir üst sınırı vardır ve sınır, makinenizin toplam belleğinden bağımsız olarak daha düşük bir değerde başlayabilir.
Yığın dolduğunda V8 önce çöp toplama (garbage collection) dener. Yani artık kimsenin kullanmadığı nesneleri temizlemeye çalışır. Temizlik yeterli yer açmazsa süreç durur ve ekranda şuna benzer bir uyarı görürsünüz: FATAL ERROR: ... JavaScript heap out of memory.
Kısacası hata, makinenin belleğinin bittiği anlamına gelmeyebilir. Çoğu zaman yalnızca V8'in kendi sınırına çarpmışsınızdır. Bu fark, çözümü seçerken çok önemlidir. Çünkü sınırı yükseltmek işe yarar, ancak sorunun nedenini ortadan kaldırmaz.
Hata metni Node.js sürümüne göre biraz değişebilir. Dolayısıyla ekranınızdaki ifade farklı görünüyorsa, benzeri bir uyarı gördüğünüzü varsayın ve aynı teşhis yolunu izleyin.
Hızlı çözüm olarak --max-old-space-size bayrağı nasıl verilir?
Bayrak, V8'in yaşlı nesneler için ayırabileceği yığın sınırını belirler. Node.js belgeleri değeri MiB (mebibayt) cinsinden tanımlar. Komutu çalıştırırken bayrağı betik adından önce yazarsınız.
node --max-old-space-size=4096 build.js
Buradaki 4096 değeri yalnızca örnektir. Doğru değer makinenizin belleğine ve aynı anda çalışan diğer işlere bağlıdır. Örneğin 8 GB belleği olan bir makinede 4096 vermek, işletim sisteminize ve diğer süreçlere de yer bırakır.
Bayrağı verdikten sonra iki sonuçtan biriyle karşılaşırsınız. Birincisinde iş tamamlanır ve sorun büyük bir ihtimalle yalnızca sıkı bir sınırdı. İkincisinde hata daha geç gelir, bu da genellikle sızıntı ya da kontrolsüz büyüme belirtisidir.
Bu yüzden sınırı birkaç kez artırıp denemek yerine bir kez artırın ve sonucu gözlemleyin. Aksi halde gerçek sorunu aylarca gizlemiş olursunuz.
NODE_OPTIONS ile bellek sınırı nasıl verilir?
Komutu doğrudan yazamadığınız yerlerde, örneğin bir paket betiği ya da CI adımı içinde, NODE_OPTIONS ortam değişkenini kullanırsınız. Bu değişken, Node.js sürecine kabul edilen bayrakları dışarıdan taşır.
export NODE_OPTIONS="--max-old-space-size=4096"
npm run build
Node.js belgelerine göre komut satırı seçenekleri, NODE_OPTIONS ile verilen seçeneklerden önceliklidir. Yani aynı bayrağı iki yerde farklı değerle verirseniz komut satırındaki kazanır. Bu ayrıntı, "ayarı verdim ama etkisi yok" şikayetlerinin sık nedenidir.
Ayrıca değişkenin gerçekten sürece ulaştığını doğrulayın. Örneğin bir derleme aracı kendi alt süreçlerini başlatıyorsa, bayrak bu alt süreçlere farklı yoldan geçebilir. Bu nedenle ayarı eklediğiniz yerde değil, hatanın çıktığı süreçte arayın.
Kalıcı kullanım için ayarı proje betiğine ya da dağıtım yapılandırmasına yazın. Böylece ekipteki herkes aynı sınırla çalışır.
Bellek sınırı değeri nasıl seçilir ve sistem belleği nasıl aşılmaz?
Değer seçerken önce makinenin gerçek belleğine bakın. Sınırı fiziksel belleğin üzerine çıkarırsanız işletim sistemi sürece yer bulmak için diske takas (swap) yapar. Bu durumda uygulama yavaşlar, hatta işletim sistemi süreci zorla kapatır.
Güvenli bir yaklaşım şudur: Makinede aynı anda çalışan diğer işleri düşün, onlara pay bırak ve kalan bölümün bir kısmını Node.js'e ver. Üstelik V8 yığını, sürecin kullandığı toplam belleğin yalnızca bir bölümüdür. Tamponlar ve yerel eklentiler yığının dışında bellek tüketir.
Sayısal bir kural vermiyoruz, çünkü doğru değer iş yüküne göre değişir. Bunun yerine şu sırayı öneriyoruz:
- Sorunlu işi izlenebilir bir ortamda çalıştırın ve bellek kullanımını gözleyin.
- Sınırı kademeli olarak yükseltin, her adımda sonucu kaydedin.
- İş bittiğinde kullanılan tepe belleğe küçük bir pay ekleyin.
- Sınırı makine belleğinin altında tutun.
Güncel varsayılan sınır sürümden sürüme değişebildiği için, bu değeri Node.js belgelerinden kontrol edin.
Bayrak neden kalıcı çözüm değil, yalnızca yara bandı?
Sınırı yükseltmek, kovayı büyütmek gibidir. Musluk açık kalmaya devam ederse kova yine dolar. Bellek sızıntısı olan bir uygulamada sınırı yükseltmek yalnızca çöküşü erteler.
Öte yandan sorun gerçekten büyük bir veri işleminden geliyorsa, yüksek sınır makul bir geçiş çözümü olabilir. Yine de bu çözüm iki risk taşır. Birincisi, çöp toplayıcı daha büyük yığını taradığı için duraklamalar uzayabilir. İkincisi, sınırı yükselttiğiniz için gerçek sorun fark edilmeden büyür.
Örnek senaryo: Bir ekip derleme hatasını sınırı artırarak çözer. Aylar sonra proje büyür ve hata geri gelir. Bu kez sınırı yeniden artırırlar. Sonunda CI makinesi yetmez hale gelir, çünkü kökteki sorun hiç incelenmemiştir.
Bu nedenle bayrağı "zaman kazandıran" bir araç olarak görün. Ardından aşağıdaki teşhis sırasına geçip kalıcı bir çözüm uygulayın.
JavaScript heap out of memory hatasının en sık nedenleri nelerdir?
Sahada gördüğümüz sıralamayı en olası nedenden başlayarak veriyoruz. Önce en sık görülen nedeni kontrol edin, çünkü zaman kazandırır.
- Büyük bir derleme (build) işlemi: Çok sayıda modül, kaynak haritası ve eklenti aynı süreçte bellek tüketir.
- Büyük veriyi tek seferde belleğe almak: Dosyanın tamamını okumak ya da büyük bir yanıtı tek parça çözmek.
- Bellek sızıntısı: Uzun süre çalışan sunucuda yavaş yavaş büyüyen bellek.
- Sınırsız önbellek ya da kuyruk: Boşaltılmayan bir liste ya da nesne.
- Kapsayıcı ya da CI sınırı: Ortamın belleği, uygulamanın ihtiyacından küçük.
Her nedenin belirtisi farklıdır. Derleme sırasında oluşan hata genellikle aynı noktada tekrar eder. Sızıntıda ise sunucu saatlerce ya da günlerce sağlıklı çalışır, sonra çöker. Bu fark, teşhisi hızlandırır.
Aşağıdaki bölümlerde her nedeni tek tek ele alıyoruz. Ayrıca bölümün sonundaki karşılaştırma tablosu, belirtiden nedene giden yolu özetler.
Büyük bir derleme sırasında bellek neden biter?
Modern önyüz projelerinde derleme aracı, tüm bağımlılık ağacını belleğe yükler. Ardından kodu dönüştürür, birleştirir ve küçültür. Proje büyüdükçe bu işlemin tepe bellek ihtiyacı da büyür.
Bu aşamada hatayı genellikle npm run build komutunda görürsünüz. Örneğin yerel makinenizde sorunsuz çalışan derleme, daha az belleği olan bir CI makinesinde çöker. Bu durumda kod değişmemiştir, yalnızca ortam değişmiştir.
Derleme kaynaklı hatalarda şu soruları sırayla sorun:
- Hata her zaman aynı adımda mı çıkıyor (örneğin küçültme aşaması)?
- Kaynak haritası üretimi açık mı?
- Aynı anda kaç dosya paralel işleniyor?
- Bağımlılıklarda yakın zamanda büyük bir değişiklik oldu mu?
Yeni bağımlılık eklerken kurulum hatası aldıysanız, npm ERESOLVE hatası rehberimiz de işinize yarayabilir. Çünkü bağımlılık çakışmasını zorla geçmek, bazen derlemeyi şişiren paketleri de getirir.
Büyük veriyi belleğe almak neden bu hatayı tetikler?
Bir dosyayı ya da veritabanı sonucunu tek seferde okumak, tüm içeriği yığına taşır. Örneğin yüzlerce megabayt boyutundaki bir CSV dosyasını tek bir metne çevirirseniz, hem ham metin hem de ayrıştırılmış nesneler bellekte durur. Böylece ihtiyacınız olan bellek, dosya boyutunun birkaç katına çıkar.
Benzer şekilde büyük bir JSON yanıtını tek parça çözmek, yanıtın kendisinden fazla bellek ister. Çünkü çözümleme sırasında ara nesneler de oluşur. Bu nedenle veri büyüdükçe kod aniden çalışmaz hale gelir.
Bu durumun tipik belirtisi şudur: Küçük örnek dosyalarla her şey çalışır, gerçek veriyle çöker. Yani hata kodun yanlışlığından değil, ölçeklenmemesinden gelir.
Çözüm yönü açıktır: Veriyi bütün olarak değil, parça parça işleyin. Bir sonraki bölümde bunun nasıl yapıldığını anlatıyoruz.
Akış (stream) ile veri işleme belleği nasıl korur?
Akış (stream), veriyi küçük parçalar halinde okuyup işleyen bir yöntemdir. Bir kova yerine borudan akan su gibi düşünün: Aynı anda yalnızca küçük bir miktar bellekte durur. Node.js belgeleri bu yapıyı akış API'si olarak sunar.
Kavramsal olarak üç adım vardır. Önce kaynağı akış olarak açarsınız. Ardından her parçayı işlersiniz. Son olarak sonucu hedefe yazarsınız. Parçalar sırayla geçtiği için bellek kullanımı dosya boyutuyla büyümez.
const { pipeline } = require('node:stream/promises');
await pipeline(girdi, donusum, cikti);
Satır tabanlı dosyalarda her satırı ayrı işlemek de aynı mantığa dayanır. Veritabanı sorgularında ise sonuçları sayfa sayfa çekmek, tüm tabloyu belleğe almaktan çok daha güvenlidir.
Akış kullanımında dikkat edeceğiniz tek nokta, hedefin yavaş olduğu durumlardır. Hedef yetişemezse veri bellekte birikebilir. Bu nedenle akış zincirini ham olay dinleyicileriyle değil, boru hattı yardımcılarıyla kurun. Ayrıntı için Node.js akış belgelerine bakabilirsiniz.
Bellek sızıntısı olduğunu nasıl anlarsınız?
Bellek sızıntısı, artık gerekmeyen nesnelerin bir yerden referans alınmaya devam etmesi yüzünden temizlenememesidir. Çöp toplayıcı yalnızca erişilemeyen nesneleri siler. Dolayısıyla bir listede unutulmuş nesne sonsuza kadar kalır.
Belirti genellikle şöyledir: Uygulama başlar, bellek kullanımı yavaşça yükselir ve hiç düşmez. Trafik azalsa bile bellek aynı kalır. Sonunda süreç çöker, yeniden başlatılır ve döngü tekrar eder.
Sızıntıya yol açan sık kalıplar şunlardır:
- Hiç temizlenmeyen genel (global) önbellekler ve nesne haritaları.
- Kaldırılmayan olay dinleyicileri.
- Kapatılmayan zamanlayıcılar ve bağlantılar.
- Her istekte büyüyen, ama boşaltılmayan diziler.
Sızıntıyı kanıtlamak için bellek kullanımını zaman içinde izleyin. Düz bir çizgi yerine sürekli yükselen bir basamak görüyorsanız şüphe güçlenir. Sunucu günlüklerini incelemek de yardımcı olur; bu konuda ücretsiz log analizi aracımızı kullanabilirsiniz.
Heap snapshot nasıl alınır ve nasıl okunur?
Heap snapshot, yığının belirli bir andaki fotoğrafıdır. Hangi nesne türünün ne kadar yer kapladığını ve kimin onu tuttuğunu gösterir. Sızıntı avında en güçlü araçtır.
Node.js belgelerine göre --heapsnapshot-signal bayrağı, belirlediğiniz bir sinyal geldiğinde sürecin yığın dökümü yazmasını sağlar. Ayrıca --heapsnapshot-near-heap-limit seçeneği, yığın sınıra yaklaştığında otomatik döküm alır. Ancak belgeler döküm almanın zaman ve bellek gerektirdiğini de belirtir.
node --heapsnapshot-signal=SIGUSR2 sunucu.js
kill -USR2 SUREC_NO
En iyi yöntem iki döküm almaktır: Biri uygulama yeni açıldığında, diğeri bellek yükseldikten sonra. Ardından ikisini karşılaştırırsınız. İkinci dökümde belirgin biçimde artan nesne türü, sızıntının izidir.
Üretim ortamında döküm alırken dikkatli olun. Döküm dosyası hassas veri içerebilir ve alma sırasında süreç yavaşlar. Bu yüzden dosyayı güvenli bir yerde saklayın ve işiniz bitince silin.
--inspect ve Chrome DevTools ile bellek nasıl incelenir?
Node.js, --inspect bayrağıyla bir hata ayıklama kapısı açar. Chrome DevTools bu kapıya bağlanır ve bellek sekmesinde yığın dökümü almanıza, nesne türlerini sıralamanıza ve referans zincirlerini izlemenize izin verir.
node --inspect sunucu.js
Bağlandıktan sonra Bellek (Memory) sekmesinde döküm alırsınız. Karşılaştırma görünümü, iki döküm arasındaki farkı listeler. Böylece hangi nesnelerin biriktiğini hızla görürsünüz. Ayrıntılı kullanım için Chrome DevTools bellek belgelerini inceleyin.
Güvenlik uyarısı: Node.js belgeleri, denetleyiciyi herkese açık bir IP ve porta bağlamanın güvensiz olduğunu belirtir. Bu nedenle hata ayıklama kapısını yalnızca yerel makinede ya da güvenli bir tünel üzerinden kullanın.
Bağlantı kurulamıyorsa sorun çoğu zaman porttadır. Bu durumda localhost bağlantıyı reddetti rehberimiz adım adım yol gösterir.
Derleme araçlarında paralellik ve kaynak haritası ayarı nasıl yapılır?
Derleme kaynaklı bellek sorunlarında iki ayar sık fark yaratır. Bunlar paralel çalışan iş sayısı ve kaynak haritası üretimidir. Ayar adları araçtan araca değiştiği için, kesin seçenek adını aracınızın kendi belgesinden doğrulayın.
Paralellikte mantık basittir. Her paralel iş kendi bellek payını ister. Dolayısıyla eşzamanlı iş sayısını azaltırsanız tepe bellek düşer, ancak derleme süresi uzar. Bellek kısıtlı bir CI makinesinde bu takas çoğu zaman değerlidir.
Kaynak haritaları ise hata ayıklamayı kolaylaştırır, fakat üretimi bellek ister. Üretim derlemelerinde daha hafif bir harita türü seçmek ya da haritayı kapatmak bellek kullanımını belirgin biçimde azaltabilir. Yine de bu karar, hata izleme ihtiyacınıza bağlıdır.
Ek olarak şunları değerlendirin:
- Kullanılmayan bağımlılıkları kaldırın.
- Büyük kütüphaneleri tümüyle değil, gereken bölümüyle içe aktarın.
- Derleme önbelleğini etkinleştirin ve temiz tutun.
Sitenizin yükleme hızı konusu da bununla ilişkilidir; ayrıntı için JavaScript'in site hızına etkisi yazımıza göz atın.
CI ve konteynerlerde bellek sınırı neden ayrı bir sorundur?
Konteynerde çalışan bir süreç, ana makinenin tüm belleğini göremeyebilir. Konteynere bir bellek sınırı verilmişse, işletim sistemi sınırı aşan süreci doğrudan sonlandırır. Bu durumda V8 hatası bile görmeden süreç kapanabilir.
İki sınırı birbirinden ayırmak gerekir. Birincisi V8'in yığın sınırıdır ve --max-old-space-size ile ayarlanır. İkincisi konteynerin ya da CI çalıştırıcısının bellek sınırıdır. V8 sınırı konteyner sınırından büyükse, V8 hata vermeden önce konteyner süreci kapatır.
Bu nedenle V8 sınırını konteyner sınırının altında tutun. Böylece hata, sessiz bir kapanış yerine okunabilir bir mesajla gelir. Konteyner kaynak sınırlarının nasıl tanımlandığı için Docker kaynak kısıtlama belgesine bakın.
Docker konusunda temelden başlamak isterseniz Docker nedir rehberimiz iyi bir çıkış noktasıdır. Unutmayın, aynı kod yerelde çalışıp CI'da çökebilir, çünkü ortamlar eşit bellek sunmaz.
PM2 ile bellek eşiğinde yeniden başlatma kullanmalı mısınız?
PM2, Node.js uygulamalarını yöneten bir süreç yöneticisidir. Bellek eşiği aşıldığında süreci otomatik yeniden başlatan bir seçeneği vardır. Eşik değerini yapılandırma dosyanızda tanımlarsınız; kesin seçenek adını PM2 belgesinden doğrulayın.
Bu özellik, sızıntı bulunana kadar kullanıcıları etkileyen çöküşleri azaltır. Yani sunucu bir gece çöküp sabaha kadar kapalı kalmak yerine, kontrollü biçimde yenilenir. Üretimde geçici bir emniyet kemeri olarak değerlidir.
Öte yandan sorunu çözmez. Yeniden başlatma, bellek sızıntısını silmez, yalnızca sonuçlarını hafifletir. Ayrıca yeniden başlatma sırasında açık bağlantılar kopabilir. Bu nedenle eşiği bir çözüm değil, bir köprü olarak düşünün.
Önerimiz şudur: PM2 eşiğini devreye alın, aynı anda heap snapshot ile sızıntıyı arayın ve bulduktan sonra eşiği emniyet olarak bırakın. PM2'yi sıfırdan öğrenmek için PM2 nedir rehberimizi okuyabilirsiniz.
JavaScript heap out of memory hatası yalnızca sunucuda mı görülür?
Hayır. Hata, Node.js ile çalışan her yerde ortaya çıkabilir. Paket kurulumu, test çalıştırıcısı, tip denetleyicisi, derleme aracı ve tek seferlik veri betikleri bunların başında gelir. Yani sorun "sunucu" kelimesine bağlı değil, Node.js sürecinin bellek davranışına bağlıdır.
Örneğin bir geliştirici, yerel makinesinde test komutunu çalıştırırken aynı hatayı alabilir. Bu durumda uzun süre çalışan bir sunucu değil, büyük bir test kümesi bellek tüketiyordur. Dolayısıyla teşhis sorusu hep aynıdır: Hangi komut, hangi aşamada, ne kadar veriyle çöküyor?
Bu ayrımı yapmak önemlidir, çünkü çözümler farklıdır. Tek seferlik bir betikte sınırı yükseltmek makul olabilir. Buna karşılık sürekli çalışan bir sunucuda aynı yaklaşım sızıntıyı gizler. Bu nedenle önce hatanın hangi tür süreçte çıktığını yazıya dökün, sonra uygun bölüme geçin.
JavaScript heap out of memory hatasında teşhis sırası nasıl olmalı?
Sahada izlediğimiz sıra, en ucuz kontrolden en pahalıya doğru ilerler. Böylece boşuna saatler harcamazsınız. Her adımda yalnızca bir şeyi değiştirin, çünkü aynı anda üç ayar değiştirirseniz hangisinin işe yaradığını anlayamazsınız.
- Hatanın hangi komutta ve hangi aşamada çıktığını kaydedin.
- Ortamı karşılaştırın: yerel makine, CI ve konteynerde bellek farkı var mı?
- Sınırı bir kez yükseltin ve hatanın gecikip gecikmediğine bakın.
- Hata gecikiyorsa bellek büyümesini zaman içinde ölçün.
- Büyüme sürekliyse iki yığın dökümü alıp karşılaştırın.
- Büyüme veriyle orantılıysa akışa ya da sayfalamaya geçin.
- Kalıcı önlemi uygulayın ve bellek alarmı ekleyin.
Bu sıranın mantığı basittir. Ortam farkı en ucuz kontroldür ve en sık neden olabilir. Döküm almak ise en pahalı adımdır, bu yüzden en sona yakın durur.
Ayrıca her denemenin sonucunu kısa bir not olarak saklayın. Hangi sınırda hatanın ne kadar geciktiğini yazarsanız, sorunun veriyle mi yoksa zamanla mı büyüdüğünü kolayca görürsünüz. Ekipçe çalışıyorsanız bu notlar, aynı teşhisin iki kez yapılmasını da önler.
Çöp toplama ve yığın büyüklüğü uygulamanın hızını nasıl etkiler?
Çöp toplayıcı çalışırken uygulama kısa süreli duraklayabilir. Yığın büyüdükçe taranacak nesne sayısı artar ve duraklamalar uzayabilir. Bu yüzden sınırı çok yüksek tutmak, hata görmeseniz bile yanıt sürelerini bozabilir.
Belirtiyi şöyle tanırsınız: Uygulama çökmüyor, ancak zaman zaman birkaç saniye donuyor. Bellek grafiğinde testere dişi gibi inip çıkan bir desen görürsünüz. Yani toplayıcı çok sık ve çok uzun çalışıyordur.
Bu durumda daha büyük yığın vermek çoğu zaman yardımcı olmaz. Bunun yerine nesne üretimini azaltmanız gerekir. Örneğin her istekte yeniden oluşturduğunuz büyük nesneleri yeniden kullanın ve geçici dizileri küçük tutun.
Kısacası bellek yalnızca çökme meselesi değildir, aynı zamanda performans meselesidir. Kalıcı çözüm, daha az bellek kullanan bir tasarımdır.
Örnek senaryo: raporlama betiğinde bu hata nasıl çözülür?
Örnek senaryo olarak, geceleri tüm sipariş kayıtlarını okuyup tek bir rapor dosyası üreten bir betik düşünün. Betik ilk aylarda sorunsuz çalışır. Kayıt sayısı büyüyünce bir gece JavaScript heap out of memory hatasıyla çöker.
Ekip önce sınırı yükseltir ve betik yeniden çalışır. Birkaç ay sonra hata geri döner. Bu kez teşhise geçerler ve betiğin tüm kayıtları tek bir dizide topladığını görürler. Yani bellek ihtiyacı, kayıt sayısıyla doğrudan büyümektedir.
Kalıcı çözüm şu adımlardan oluşur:
- Kayıtları sayfa sayfa çekmek.
- Her sayfayı işleyip çıktıya hemen yazmak.
- İşlenen sayfayı bellekten bırakmak.
- Betiğin tepe bellek kullanımını bir kez ölçüp not etmek.
Böylece bellek kullanımı kayıt sayısından bağımsız hale gelir. Bu senaryo kurgudur, ancak sahada sık gördüğümüz bir kalıbı yansıtır.
Hangi durumda bayrak yerine mimariyi değiştirmelisiniz?
Bazı işler bellekte yapılmak için uygun değildir. Çok büyük dosyaların dönüştürülmesi, dev veri kümelerinin birleştirilmesi ya da ağır görüntü işleme bunlara örnektir. Bu işleri ana uygulama sürecinde çalıştırmak, tüm kullanıcıları riske atar.
Bu nedenle ağır işleri ayrı bir sürece ya da kuyruk tabanlı bir işçiye taşıyın. Böylece bellek sorunu yalnızca o işçiyi etkiler, ana uygulama çalışmaya devam eder. Üstelik işçiye ayrı bellek sınırı verebilirsiniz.
Öte yandan her sorun mimari değişiklik gerektirmez. İş küçükse ve tek seferlikse, sınırı yükseltmek yeterlidir. Karar verirken şunu sorun: Bu iş büyümeye devam edecek mi? Cevap evet ise mimariyi şimdi düzeltmek, sonradan düzeltmekten ucuzdur.
Hangi yöntemi ne zaman seçmelisiniz?
Aşağıdaki tablo, yöntemleri kullanım zamanı ve risk açısından karşılaştırır. Tablo, bu yazıdaki teşhis sırasının özetidir.
| Yöntem | Ne zaman kullanılır | Risk |
|---|---|---|
| Bellek sınırını yükseltme | Acil durumda geçici çözüm gerekir | Sızıntıyı gizler, duraklamaları uzatır |
| Akış ile işleme | Büyük dosya ya da veri kümesi var | Kodun yeniden yazılması gerekir |
| Heap snapshot | Bellek zamanla büyüyor | Üretimde yavaşlatır, hassas veri içerebilir |
| Derleme ayarları | Hata yalnızca build sırasında çıkıyor | Süre uzar, hata izleme zayıflar |
| Konteyner sınırını artırma | Sessiz kapanışlar yaşanıyor | Maliyet artar |
| PM2 bellek eşiği | Sızıntı bulunana kadar köprü gerekir | Bağlantılar kopabilir |
Tabloyu okurken şuna dikkat edin: Hiçbir yöntem tek başına yeterli değildir. Çoğu gerçek durumda önce sınırı yükseltir, sonra nedeni bulur ve en sonunda kalıcı yöntemi uygularsınız.
Kalıcı önlem için hangi kontrol listesini izlemelisiniz?
Sorunu çözdükten sonra tekrarını önlemek için şu listeyi uygulayın. Liste, yazılım ekipleri için kısa bir bakım rutinidir.
- Bellek kullanımını düzenli izleyin ve alarm eşiği tanımlayın.
- Büyük veriyi her zaman akışla ya da sayfalayarak işleyin.
- Önbelleklere boyut sınırı ve süre sonu ekleyin.
- Olay dinleyicilerini ve zamanlayıcıları iş bitince kaldırın.
- CI ve konteyner bellek sınırlarını belgeleyin.
- Bağımlılıkları düzenli güncelleyin ve gereksizleri silin.
- Üretimde PM2 gibi bir yöneticiyle emniyet eşiği kullanın.
- Her büyük sürüm öncesi bellek testini bir kez çalıştırın.
Kısacası amaç, hatayı beklemek yerine belleği görünür kılmaktır. Böylece sorun kullanıcıya ulaşmadan yakalanır.
Ekip içinde bu listeyi bir bakım takvimine bağlamak da işe yarar. Örneğin her sürüm öncesinde bellek kontrolünü ortak bir adım haline getirirseniz, sorun üretime çıkmadan önce yakalanır. Üstelik yeni gelen geliştiriciler de bellek konusunda aynı alışkanlığı kazanır.
Sunucuda Node.js uygulaması çalıştırıyorsanız, kurulum ve dağıtım adımlarını ele aldığımız Node.js kurulum ve dağıtım rehberine de göz atın.
Bu sorunda ekipten nasıl destek alabilirsiniz?
Bellek sorunları bazen yalnızca bir ayarla çözülmez. Sızıntı avı, derleme hattı optimizasyonu ya da büyük veri akışı yeniden tasarımı zaman ve deneyim ister. Bu noktada Talha Aslan ve ekibi olarak özel yazılım geliştirme hizmetimizle destek veriyoruz.
İhtiyacınızı kısaca anlatın, kapsamı birlikte netleştirelim. Hizmetimizle ilgili ayrıntılar için özel yazılım geliştirme sayfamıza bakın ve oradan teklif isteyin.
Bu yazıdaki adımlar çoğu durumda kendi başınıza ilerlemeniz için yeterlidir. Ayrıca kardeş yazılarımızdaki npm ve localhost rehberleri, aynı geliştirme ortamında sık karşılaşılan sorunları kapsar.
Not: Bu içerik genel bilgi amaçlıdır. Komut ve ayar adlarını kullandığınız Node.js sürümünün resmi belgesinden doğrulayın, çünkü seçenekler zamanla değişebilir. Ayrıca asıl kaynak olarak Node.js komut satırı belgesini kullanın.



