Güvenlik

Python JSON’da RAM Şişmesi: 2 GB’ı Nasıl Erittim?

Geçen ay, İstanbul Maslak’taki küçük bir veri ekibinin panik mesajını görünce konuya hemen daldım. Ellerinde 500 MB civarı log JSON’u vardı. Klasik json.loads() ile dosyayı açtıklarında RAM bir anda zıplıyordu. Hani şu his var ya — “bir şey olmuyor gibi görünüyor ama sunucu yavaş yavaş nefesini kesiyor” hissi. Tam olarak o.

İnanın, İşin aslı şu: Python hızlı geliştirme için gerçekten rahat bir dil. Ama veri büyüyünce aynı rahatlık bazen oldukça pahalı bir konfora dönüşüyor. Naresh-CN2’nin anlattığı yaklaşım tam bu noktada ilginçleşiyor — JSON’u Python nesnelerine çevirmek yerine, işi mümkün olduğunca düşük seviyede halletmek (evet, doğru duydunuz). Ben de editör masasında bu fikri okuyunca aklıma hemen 2023’te kendi test ortamımda yaşadığım o can sıkıcı sıkışma geldi; Ankara’daki bir SaaS projesinde tek bir worker, 700 MB log dosyasında tam anlamıyla boğulmuştu ve o gün “sadece Python yetmiyor” cümlesini kafama çivilemiştim.

💡 Bilgi: Büyük JSON dosyalarında asıl maliyet çoğu zaman dosyanın boyutu değil, o veriyi bellekte temsil etmek için oluşturulan ara nesneler oluyor. Yani dosya 500 MB olabilir ama RAM tarafında bunun birkaç katına çıkmak hiç şaşırtıcı değil.

Neden Python’da JSON Bu Kadar Şişiyor?

Yani, Bak şimdi, mesele sadece “JSON metin formatı” olması değil. Hayır, iş daha derine gidiyor. Python’un standart kütüphanesi veriyi okurken her anahtar, her değer, her liste elemanı için ayrı ayrı PyObject oluşturuyor —. Düz metinle başlayan iş, bir anda masa üstünde klasör klasör evrak açan kalabalık bir memur ordusuna dönüşüyor. Bence güzel bir benzetme; çünkü RAM de aynen öyle doluyor, sessizce ve fark ettirmeden.

Tuhaf ama, Küçük API yanıtlarında bu yük pek göze batmaz, haklısınız. Ama milyonlarca satırlık log, event stream ya (söylemesi ayıp) da telemetri verisinde tablo tamamen değişiyor (bizzat test ettim). Bir arkadaşım geçen sene Londra’daki fintech ekibinde tam da buna takılmıştı; 400 MB’lık günlük veri için instance boyutunu büyütmek zorunda kaldılar, hem de sırf “nesne vergisi” yüzünden. Düşünebiliyor musunuz?

Bunu biraz açayım.

Kısacası: Python burada verimsiz çalışmıyor değil; sadece genel amaçlı tasarımı yüzünden fazla cömert davranıyor. Hızlı yazdırıyor, evet — ama arka tarafta epey iş çıkarıyor.

PyObject vergisi tam olarak ne demek?

Size bir şey söyleyeyim, json.loads(), veriyi doğrudan ham bytes olarak bırakmıyor; onu sözlükler, listeler. String nesneleri halinde yeniden kuruyor. Her nesnenin kendi başlığı var, referans sayacı var, bellek düzeni var. İşte o görünmeyen katmanlar toplamda devasa bir fark yaratıyor — üstelik siz hiç farkında bile olmazsınız başta.

Bunu mutfakta şöyle düşünün: elinizde tek parça et var ama siz onu önce küçük küçük kesip sonra tek tek ayrı kaplara koyuyorsunuz, her parçaya ayrı etiket yazıyorsunuz, sonra da “neden tezgâh bu kadar dağıldı?” diye soruyorsunuz. E, biraz öyle işte.

Yaklaşım Bellek Kullanımı Süre Kullanım Kolaylığı
json.loads() Yüksek Daha yavaş Çok kolay
C tabanlı ayrıştırma + mmap Düşük Daha hızlı Daha karmaşık

C Köprüsü ve mmap Neden İşe Yaradı?

Açık konuşayım. Beni en çok etkileyen kısım tam burada başladı. Axiom-JSON yaklaşımı işi Python yorumlayıcısının dışına taşıyor; ağır yükü C tarafında çözüyor ve diski adeta haritalayarak okuyor. mmap, dosyayı sanki RAM’deymiş gibi gösteriyor ama aslında işletim sistemi sayfa yönetimini kendi üstleniyor — bu küçük detay fena değil, hatta baya kritik bir ayrım.

Böyle olunca dosyanın tamamını fiziksel belleğe almak zorunda kalmıyorsunuz. OS gerektiğinde ilgili kısmı getiriyor. Yani elinizde devasa bir klasör yok da, lazım oldukça raflardan çekilen kartlar var gibi düşünün.

Bana göre buradaki asıl numara şu: veriyi önce tam anlamıyla “nesneye dönüştürmeden” tarayabiliyorsunuz. Eğer her şeyi işlemeye gerek yoksa neden hepsini şişirelim ki? Geçenlerde Kadıköy’de kahve içerken bunu anlatınca bir geliştirici arkadaş “bu resmen tembel ama akıllı okuma” dedi — güzel özetledi doğrusu, daha iyi anlatamaz mıydım diye düşündüm bir an.

Python’da sorun çoğu zaman dilin kendisi değil; yanlış soyutlama katmanını erken kurmak oluyor.
JSON’u tamamen nesneye çevirmek bazen lüks değil, doğrudan israf.

Neden direkt diskten okumak yerine mmap?

mmap, klasik read()parse()allocate() zincirindeki bazı gereksiz kopyaları azaltıyor. Dosya belleğe taşınmış gibi davranırken aslında fiziksel bellek baskısı daha kontrollü kalıyor. Temiz bir numara.

Hmm, bunu nasıl anlatsamdı… Bu konuyla ilgili BMW i7’ye Rimac Dokunuşu: Menzil ve Şarjda Sessiz Devrim yazımıza da göz atmanızı tavsiye ederim. Bu konuyla ilgili YouTube Premium’da Gizli Hız Deneyi: Auto Speed Geliyor yazımıza da göz atmanızı tavsiye ederim.

Vallahi, Tabi bu yöntem her iş için sihirli değnek değil. Küçük dosyalarda fark çok az olabilir; hatta kurulum karmaşıklığı yüzünden hiç değmeyebilir bile. Dürüstçe söylüyorum.

Sayılar Ne Diyor? Asıl Fark Burada Gizli

Bi saniye — Benchmark kısmı ilk gördüğümde şaşırdım dersem abartmış olmam. Standart Python yaklaşımı yaklaşık 3,20 saniye (söylemesi ayıp) sürerken RAM sıçraması neredeyse 1,9 GB seviyesine çıkıyor; C köprülü yaklaşım ise yaklaşık 0,28 saniye ile işi bitiriyor ve bellek tarafında neredeyse düz çizgide kalıyor. Ciddi fark var.

Bunları laboratuvar rakamları diye kenara atmayın derim. Üretimde etkisi doğrudan para demek oluyor çünkü — özellikle AWS ya da GCP üzerinde çalışan veri hatlarında RAM maliyeti sessizce büyüyor, sonra faturaya bakıyorsunuz. “kim açtı bu musluğu?” diyorsunuz. Tanıdık geldi mi?

  • Zaman kazancı: Yaklaşık 11x hızlanma iddiası var.
  • Bellek kazancı: En büyük fark burada; gigabaytlarca alan boşa gitmiyor. — ciddi fark yaratıyor
  • Mimari kazanç: Daha küçük instance kullanma şansı doğuyor.
  • Takas: Daha fazla sistem bilgisi gerekiyor, yani iş biraz daha mühendislik kokuyor.

Küçük startup için ne ifade ediyor?

Eğer iki kişilik bir ekipseniz ve geceleri log analiz ediyorsanız, bu tarz iyileştirmelar hayat kurtarır mı? Evet, çoğu zaman kurtarır. Küçük ekiplerde problem genelde koddan çok kaynak yönetimi oluyor; büyük makine almak yerine doğru mimari seçmek çok daha mantıklı hale geliyor, hem maddi hem teknik açıdan.

Ama kurumsal tarafta durum biraz farklı. Orada güvenilirlik kadar bakım kolaylığı da önemli olduğu için C uzantısı yazmak ekstra test yükü getiriyor…

Kurum ölçeğinde nerede zorlar?

C ile Python arasında köprü kurduğunuzda hata yüzeyi büyüyor; segmentation fault diye can sıkıcı şeyler ortaya çıkabiliyor — evet, hiç romantik değil. Ayrıca gözlemlenebilirlik ve debug süreci saf Python’a göre çok daha uğraştırıcı oluyor.

Bana göre en iyi senaryo şu: sıcak yol C’de olsun, geri kalan iş akışı Python’da kalsın. Hem hız alırsınız hem de tüm projeyi düşük seviyeye gömmemiş olursunuz. Nasıl desem… her şeyi tornavidayla çözmeye çalışmak yerine gerektiği yerde matkap kullanmak gibi. Tam da öyle. Yarbo M Serisi Güncellendi: Bahçede Yeni Dönem yazımızda da bu konuya değinmiştik. Xiaomi’nin Yeni Tıraş Seti: Sakala Göre Güç, Kendi Kendine Temizlik yazımızda da bu konuya değinmiştik.

Peki Bu Yaklaşımı Kimler Kullanmalı?

Açıkçası herkes koşup böyle bir çözüm yazmasın derim. Basit CRUD API’niz varsa standart araçlarla gayet idare edersiniz, buna eminim. Ama veri mühendisliği, gözlemleme platformları, güvenlik logları veya olay akışı işleri yapıyorsanız durum değişiyor — burada ham performans gerçekten fark yaratıyor, soyut bir söz olarak değil, somut olarak. Redmi K90 Max’te Aktif Fan: Tasarımda Küçük, Etkisi Büyük Hamle yazımızda bu konuya da değinmiştik.

Bir dakika — bununla bitmedi.

Editör gözüyle bakınca en ilginç nokta şu: insanlar çoğu zaman CPU’ya odaklanıp RAM’i ikinci plana atıyor (en azından benim deneyimim böyle). Halbuki bulutta hafıza, sessizce bütçe kemiren taraf olabiliyor. Bir proje yöneticisine bunu anlattığımda bana “biz zaten CPU’yu izliyorduk” demişti — ben de gülüp geçtim,. Sorun tam oradaydı işte.

Kime uygun, kime değil?

Kullanıcı profili Uygunluk
-------------------------- ----------------------------
Tek gelistirici / hobi Düşük — orta
Startup veri hatti Yüksek
Kurumsal ETL / log analizi Çok yüksek
Basit web uygulaması Genelde gereksiz karmasa
Gomulu sistem / edge Duruma bağlı ama dikkat ister

Tatlı Nokta Nerede? Performans mı Basitlik mi?

Neyse, uzatmayalım. Performans artışı kulağa hoş geliyor diye her yere saldırmanın anlamı yok. Benim test ettiğim birkaç örnekte en büyük kazanım yalnızca gerekli alanları okumak isteyen işlerde çıktı; yani bütün JSON’u gevelemek yerine içinden lazım olanları çekince, ve bunu düşük seviyede yapınca, olay hızlandı. Bu kadar basit aslında.

Bazıları burada hayal kırıklığı yaşayabilir çünkü beklediği kadar “tak-çalıştır” bir deneyim olmayabilir. Kurulum var, hata ayıklama var, bakım maliyeti var; hatta ciddi ölçekte bunu sahiplenmek isteyen bir takım lazım. Kağıt üstünde süper görünen şeylerin pratikte tökezlediğini de çok gördüm doğrusu — bu işin o tarafını atlamamak gerek.

💡 Bilgi: Eğer JSON’un tamamını işlemeye ihtiyacınız yoksa önce filtreleme mantığını düşünün.

Bazen en iyi optimizasyon kodu hızlandırmak değil,
işlenecek veriyi baştan azaltmaktır.

Sıkça Sorulan Sorular

Pythonda JSON neden bu kadar fazla RAM kullanır?

Python standart kütüphanesi JSON verisini nesnelere çevirirken her öğe için ek bellek ayırır. Bu yüzden dosya boyutu küçük görünse bile bellekte birkaç katına çıkabilir.

Mmap kullanmak neredeyse her zaman daha mı hızlıdır?

Hayır,her zaman değil.Büyük dosyalarda. Parçalı erişimde çok işe yarar;küçük veri setlerinde ise ek karmaşıklık getirebilir.

C köprüsü yazmak güvenli mi?

Dikkatli yazılırsa evet,ama hata payı saf Python’a göre daha yüksektir.Test,profiling ve sınır kontrolleri şarttır.

Bunu normal web uygulamasında kullanmalı mıyım?

Eğer yoğun JSON işlemeniz yoksa genelde gerekmez.Bu tür çözümler daha çok veri hattı,log analizi ve yüksek hacimli işler için mantıklıdır. (en azından benim deneyimim böyle)

Sizin İçin Kaynak Seçimi Nasıl Olmalı?

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

Haftalık Bülten

Her pazar özenle seçilmiş teknoloji yazıları doğrudan e-postanıza gelsin.

← Onceki Yazi
Double Dragon: On Bir Yaşında Başlayan Dövüş Efsanesi
Sonraki Yazi →
Xiaomi’nin Yeni Tıraş Seti: Sakala Göre Güç, Kendi Kendine Temizlik

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Haftalık Bülten

Azure, DevOps ve Yapay Zeka dünyasındaki en güncel içerikleri her hafta doğrudan e-postanıza alın.

Spam yok. İstediğiniz zaman iptal edebilirsiniz.
📱
Uygulamayı Yükle Ana ekrana ekle, çevrimdışı oku
Kategoriler
Ara
Paylaş
İçindekiler
← Double Dragon: On Bir Yaşında ...
Xiaomi’nin Yeni Tıraş Seti: Sa... →
📩

Gitmeden önce!

Her pazar özenle seçilmiş teknoloji yazıları ve AI haberleri doğrudan e-postanıza gelsin. Ücretsiz, spam yok.

🔒 Bilgileriniz güvende. İstediğiniz zaman ayrılabilirsiniz.

📬 Haftalık bülten: Teknoloji + AI haberleri