Berk Akademi
Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

Arduino "Sketch uses too much memory" Hatası Nasıl Çözülür?

arduino-sketch-uses-too-much-memory-hatasi-nasil-cozulur
Bu yazıda neler var?
  1. İki bellek türü, iki farklı sorun
  2. Program belleği (flash) doluysa ne yapmalı
  3. RAM (Dinamik Bellek) Doluysa Ne Yapmalı
  4. Kart Seçiminin Etkisi
  5. Kodu Parçalara Ayırarak Test Etme Yöntemi
  6. Özet

Arduino IDE'de "Sketch uses too much memory" hatasını çözmek için önce sorunun program belleğinden (flash) mi yoksa çalışma zamanı belleğinden (RAM/SRAM) mi kaynaklandığını belirlemeniz gerekir. Flash doluysa kütüphaneleri sadeleştirmek, string'leri F() makrosuyla RAM'den flash'a taşımak ve kod tekrarını azaltmak işe yarar. RAM doluysa global değişkenleri küçültmek, dinamik bellek kullanımını sınırlamak ve gereksiz büfer/dizileri kaldırmak gerekir. Her iki durumda da kalıcı çözüm için genellikle daha fazla belleğe sahip bir karta geçmek en pratik yoldur.

İki bellek türü, iki farklı sorun

Arduino kartlarında iki ayrı bellek alanı vardır ve "too much memory" hatası bu ikisinden birinin ya da her ikisinin dolmasından kaynaklanabilir. Flash (program belleği), derlenmiş kodunuzun ve sabit verilerin (örneğin string literal'ların) saklandığı yerdir. RAM (SRAM) ise program çalışırken global değişkenlerin, dizilerin ve fonksiyon çağrılarında oluşan yerel değişkenlerin (stack) tutulduğu alandır. Bu iki bellek birbirinden bağımsız çalışır; biri dolu diye diğeri de dolu olmak zorunda değildir.

Arduino IDE, derleme sonrasında her ikisi için de ayrı ayrı kullanım bilgisi verir. Örnek bir çıktı şöyle görünebilir (aşağıdaki değerler temsilidir, kart ve sketch'e göre değişir):

Sketch uses 28450 bytes (92%) of program storage space. Maximum is 30720 bytes.
Global variables use 1650 bytes (80%) of dynamic memory, leaving 398 bytes for local variables. Maximum is 2048 bytes.

Bu iki satır aslında iki farklı problemi işaret eder. İlk satır flash doluluğunu, ikinci satır RAM doluluğunu gösterir. Genel bir pratik kural olarak kullanım yüzdesi %90'ı geçtiğinde kritik seviyeye yaklaşıldığı kabul edilir; ancak bu kesin bir teknik standart değil, deneyimle oluşmuş bir güvenlik payı yaklaşımıdır. Flash taşması IDE tarafından derleme sırasında yakalanır ve net bir hata olarak karşınıza çıkar. RAM taşması ise çoğu zaman derleme aşamasında görülmez; program çalışırken stack ile global değişkenlerin alanı çakışır ve kart beklenmedik şekilde donar, resetlenir ya da tuhaf davranışlar sergiler. Bu yüzden RAM sorunlarını tespit etmek flash sorunlarına göre daha zordur.

Program belleği (flash) doluysa ne yapmalı

Flash doluluğunun en yaygın nedeni gereksiz veya ağır kütüphanelerdir. Her #include satırı, kullanılmasa bile o kütüphanenin bir kısmını sketch'e dahil edebilir. Bir kütüphanenin gerçek maliyetini görmek için basit bir yöntem, o kütüphaneyi geçici olarak kaldırıp derleme çıktısındaki bayt sayısındaki farkı karşılaştırmaktır. Örneğin Servo.h kütüphanesini dahil ettiğinizde flash kullanımının belirgin şekilde arttığını görebilirsiniz; kütüphaneyi satırdan çıkarıp yeniden derleyerek bu farkı ölçebilirsiniz. Gerçek büyüklük Arduino IDE sürümüne ve hedef karta göre değişir, bu yüzden kesin bir bayt değeri vermek yerine bu karşılaştırma yöntemini kullanmak daha güvenilirdir.

İkinci yaygın neden string literal'lardır. AVR tabanlı kartlarda (Uno, Nano, Mega gibi) "Merhaba" gibi sabit metinler varsayılan olarak hem flash'a yazılır hem de program başlarken RAM'e kopyalanır; bu da hem flash'ı hem RAM'i tüketir. F() makrosu bu metinleri flash'ta bırakıp RAM'e kopyalanmasını önler:

Serial.println(F("Merhaba Dunya"));

Bu davranış AVR mimarisine özgüdür; SAMD veya ARM tabanlı kartlarda (Due, Zero, MKR serisi gibi) bellek mimarisi farklı çalıştığı için string'lerin RAM'e kopyalanması sorunu bu ölçüde geçerli değildir, dolayısıyla F() makrosunun kazancı bu kartlarda sınırlıdır.

Son olarak, aynı işlevi gören kod bloklarının tekrar tekrar yazılması flash'ı gereksiz yere büyütür. Benzer kod parçalarını bir fonksiyona taşımak, derleyicinin aynı talimatları tek bir yerde tutmasını sağlar ve toplam program boyutunu küçültür.

RAM (Dinamik Bellek) Doluysa Ne Yapmalı

RAM sorunu, flash bellek sorunundan farklı bir mantıkla ele alınır. Çünkü burada mesele sadece kodun boyutu değil, çalışma zamanında verinin ne kadar yer kapladığıdır. Bu tür sorunların en sık görülen üç nedeni var.

Büyük diziler ve buffer'lar

Sensör verilerini geçici olarak tutmak için oluşturulan diziler, çoğu zaman fark edilmeden RAM'i tüketir. Örneğin 1000 elemanlı bir int dizisi tanımladığınızda, her int değeri 2 byte yer kapladığı için toplamda 2000 byte'lık bir alan ayrılır. 8-bit AVR tabanlı bir Arduino kartında bu, mevcut RAM'in önemli bir kısmını tek bir değişkene harcamak anlamına gelebilir. Buffer boyutunu gerçekten ihtiyaç duyduğunuz kadar tutmak, sorunun büyük kısmını çözer.

Veri tipi seçimi

Her değişken için "varsayılan" tipi kullanmak yerine, değerin gerçekte hangi aralıkta olacağını düşünmek gerekir. int tipi 2 byte yer kaplar ve -32768 ile 32767 arasındaki değerleri tutabilir (bu değerler 8-bit AVR tabanlı kartlar için geçerlidir; 32-bit mimarideki bazı Arduino kartlarında int boyutu farklılık gösterebilir, bu yüzden kullandığınız kartın referans sayfasından kontrol etmekte fayda var). Eğer değeriniz 0-255 arasında kalıyorsa, byte veya uint8_t gibi 1 byte'lık bir tip kullanmak, aynı işi yarı bellekle yapmanızı sağlar. Benzer şekilde int8_t de 1 byte'tır ama -128 ile 127 arasındaki işaretli değerleri tutar. Onlarca değişkende yapılan bu tür küçük tasarruflar, toplamda ciddi bir RAM alanı geri kazandırabilir.

String sınıfının riski

Arduino'nun String sınıfı kullanımı kolay olsa da, arka planda dinamik bellek ayırma (heap allocation) yapar. Sık sık string birleştirme veya değiştirme işlemi yapıldığında bellek parçalanmasına (fragmentation) yol açabilir. Bu durum, toplam boş RAM yeterli görünse bile, sketch'in bir süre sonra çökmesine neden olabilir çünkü bellek küçük parçalara bölünmüş olur ve büyük bir blok talep edildiğinde karşılanamaz. Bunun yerine sabit karakter dizileri (char[]) kullanmak veya sabit metinleri flash bellekte tutmak için F() makrosunu kullanmak (örneğin Serial.print(F("Merhaba"))) hem RAM tasarrufu sağlar hem de bu tür kararsızlıkları önler.

Kart Seçiminin Etkisi

Bellek sorunlarının bir kısmı, aslında kod sorunu değil kart seçimi sorunudur. Arduino Uno gibi giriş seviyesi kartlar, sınırlı flash ve RAM kapasitesiyle gelir; bu da onları basit projeler için uygun kılarken, büyük kütüphaneler veya karmaşık veri yapıları kullanan projelerde hızla yetersiz kalmasına neden olur. Arduino Mega gibi daha yüksek kapasiteli kartlar veya ARM tabanlı kartlar (örneğin güncel Nano, Due, Zero veya Portenta serisindeki modeller), hem flash hem RAM açısından çok daha geniş bir çalışma alanı sunar.

Burada önemli bir nokta var: kesin kapasite rakamları karta, kullanılan IDE sürümüne ve core (çekirdek) sürümüne göre değişebilir. Bu yüzden "hangi kartta ne kadar bellek var" sorusunun cevabını, Arduino IDE'deki Boards Manager üzerinden veya kartın resmi teknik özellikler sayfasından teyit etmek en güvenilir yoldur. Eğer sürekli bellek sınırlarıyla boğuşuyorsanız, kodu optimize etmek yerine daha yüksek kapasiteli bir karta geçmek çoğu zaman daha pratik bir çözüm olur.

Kodu Parçalara Ayırarak Test Etme Yöntemi

Bellek sorununun kaynağını bulmak bazen tahminden çok sistematik bir yaklaşım gerektirir. Bunun için izlenebilecek basit bir yöntem şöyledir:

  1. Sketch'inizin bir kopyasını alın, böylece orijinal kod güvende kalır.
  2. Şüphelendiğiniz bölümü (bir kütüphane çağrısı, bir fonksiyon veya bir dizi tanımı) yorum satırına alın.
  3. Sketch'i yeniden derleyin.
  4. Derleme çıktısındaki flash ve RAM kullanım yüzdelerini kaydedin.

Bu işlemi kodun farklı bölümleri için tekrarlayarak, hangi bölümün bellek kullanımını en çok etkilediğini net bir şekilde görebilirsiniz. Yüzdelerdeki değişim büyükse, o bölüm optimizasyon için öncelikli hedefinizdir. Bu yöntem, özellikle birden fazla kütüphane kullanılan projelerde, sorunun tam olarak nereden kaynaklandığını tahmin etmek yerine ölçmenizi sağlar.

Özet

"Sketch uses too much memory" hatasıyla karşılaşıldığında ilk adım, derleyicinin verdiği çıktıyı dikkatli okumaktır. Hata programın flash bellekte mi yoksa RAM'de mi sınıra ulaştığını açıkça belirtir; çözüm yolu buna göre şekillenir. Flash bellek doluysa gözden geçirilecek yerler kod boyutunu şişiren gereksiz kütüphaneler, kullanılmayan fonksiyonlar ve string sabitlerinin tutulma şeklidir; F() makrosuyla metin sabitlerini flash'ta bırakmak bu noktada pratik bir çözümdür. RAM doluysa dikkat global değişkenlere, dizilere ve özellikle çalışma zamanında büyüyen buffer'lara kaymalıdır; int yerine byte gibi daha küçük veri tiplerini kullanmak ve gereksiz büyük dizileri sorgulamak RAM baskısını azaltır. Kart seçimi de bu sürecin bir parçasıdır: proje büyüdüğünde daha fazla flash ve RAM sunan bir karta geçmek pratik bir çıkış noktası olabilir. Bütün bu adımlar yetersiz kalırsa kodu parçalara ayırıp her parçayı ayrı ayrı derleyerek hangi bölümün belleği asıl tükettiğini tespit etmek sorunu netleştirir.

Sonuçta bu hata, kartın fiziksel sınırlarının kodun ihtiyaçlarıyla karşılaştığı bir uyarıdır; doğru teşhisle çoğu zaman küçük düzenlemelerle aşılabilir.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara