Geliştirmede donma — nedir, nedenleri ve optimizasyon yöntemleri

Yazar: IT Sectr Yayınlanma: 2026-07-28 Okuma süresi: 8 dk

Donma, bir mobil uygulamanın yavaş ve düzensiz çalıştığı durumu kullanıcının tanımlamasıdır: bazen normal yanıt verir, bazen aniden birkaç saniyeliğine donar. Teknik bağlamda, “donma” sık GC duraklamaları, ana iş parçacığının senkron işlemlerle bloke edilmesi ve optimal olmayan veri yapılarından kaynaklanan lag ve mikro donmaların bir kombinasyonu anlamına gelir. Android Performance Benchmarking Guide'a göre, yanıt süresini 300 ms'den 100 ms'ye düşürmek kullanıcı tutma oranını %25 artırır. Donmayı teşhis etmek, CPU ve Bellek profillemesinin çöp toplama sıklığı analiziyle birleşimini gerektirir.

Önemli noktalar

  • Donma, normal performansla dönüşümlü olarak gerçekleşen aralıklı bir uygulama yavaşlamasıdır
  • Ana nedenler — sık GC duraklamaları, UI iş parçacığında senkron işlemler, sayfalama olmadan bağdaştırıcılarda büyük veri hacimleri
  • Teşhis, darboğazları bulmak için CPU Profiler ve GC sıklığını ve süresini analiz etmek için Memory Profiler gerektirir
  • Çözüm, sayfalama (Paging 3) uygulamasını, Room aracılığıyla SQL sorgularını optimize etmeyi ve ağır görevleri WorkManager'e aktarmayı içerir
  • Korunma — Benchmark Baseline Profiles, AOT derlemesi, sıcak kod yollarında ayırmaları en aza indirme

Mobil geliştirmede “donma” ne anlama gelir

Donma, kullanıcıların öznel olarak yavaş uygulama performansını tanımlamak için kullandıkları resmi olmayan bir terimdir. Sabit bir gecikme olarak ortaya çıkan lag'ın aksine, donma düzensiz takılmalardan oluşur: uygulama birkaç saniye mükemmel çalışabilir ve ardından aniden 1–3 saniye “düşünebilir”.

Olayın teknik açıklaması

Profilleme perspektifinden bakıldığında, donma, tepe gecikmeleri 100 ms'yi aşan bir dizi atlanmış kare (jank) olarak kendini gösterir. Bir FPS grafiğinde bu, keskin düşüşler olarak görünür: saniyede 60 → 20 → 55 → 10 kare. Düşük FPS'li bir lag'ın aksine, donma belirgin bir değişkenliğe sahiptir.

Kullanıcı algısı

Bir uygulama donduğunda, kullanıcı yavaşlamanın mantığını anlayamaz: ekran pürüzsüz kayabilir ve ardından aniden bir saniyeliğine durabilir. Bu hayal kırıklığına neden olur ve uygulamaya olan güveni azaltır. Google'a göre, kullanıcıların %53'ü yükleme 3 saniyeden uzun sürerse bir siteyi veya uygulamayı terk eder.

Uygulamalarda ani yavaşlamaların nedenleri

Donmanın aralıklı doğası, sorunun sürekli aşırı yükten değil, olay odaklı faktörlerden kaynaklandığını gösterir. Tipik senaryoları inceleyelim.

Nesne ayırma sırasında GC duraklamaları

Android'de, ART çalışma zamanında, çöp toplama tüm uygulama iş parçacıklarını durdurur. Kod çok sayıda geçici nesne oluşturuyorsa — örneğin, her onBindViewHolder çağrısında birleştirme yoluyla yeni bir String oluşturma — GC daha sık çalışır. Bir duraklama, yığın boyutuna ve nesne nesline bağlı olarak 5–50 ms sürebilir. Kullanıcı bunu ani bir “düşünme” olarak algılar.

UI iş parçacığında senkron SQL sorguları

Android'de Room ve iOS'ta Core Data, asenkron sorguları destekler, ancak geliştiriciler basitlik için genellikle getValue() çağrısı yapar veya runBlocking aracılığıyla sorguları çalıştırır. 10.000 satırlık bir tabloda birleştirmeleri olan ağır bir SELECT 200–500 ms sürebilir ve bu süre zarfında UI'yı tamamen bloke eder.

Küçültme olmadan görüntü kod çözme

Bir kamera görüntüsünü (12 MP, 4000x3000 piksel) ölçeklemeden yüklemek, Bitmap kod çözme için 200 ms'ye kadar sürer. Görüntüler asenkron olarak ancak sınırlı bir iş parçacığı havuzu olmadan yükleniyorsa, 5–6 kod çözmenin aynı anda çalıştırılması CPU'yu aşırı yükleyerek göç eden yavaşlamalara neden olabilir.

  • Android — döngülerde dize birleştirme, sıcak yollarda nesne oluşturma, inSampleSize olmadan Bitmap
  • iOS — çok sayıda nesne içeren autorelease havuzları, ölçeklemesiz imageWithContentsOfFile, senkron URLSession
  • Platformlar arası — UI iş parçacığında JSON ayrıştırma, sunucu yanıtı beklerken ana iş parçacığında veri yükleme

Android ve iOS'ta donmalar nasıl teşhis edilir

Aralıklı yavaşlamaları teşhis etmek, sabit lag'ları teşhis etmekten daha zordur çünkü sorun her çalıştırmada tekrarlanmayabilir. Uzun bir süre boyunca istatistik toplanması gerekir.

GC olay kaydı ile Memory Profiler

Android Studio Memory Profiler yalnızca bellek kullanımını değil, aynı zamanda GC olaylarını da gösterir: sıklık, tür (Concurrent, Full), süre. Boşta durumda GC 5 saniyede bir defadan fazla meydana geliyorsa — bu aşırı ayırmanın bir işaretidir. Donma anında bir yığın dökümü almak, hangi nesnelerin belleği işgal ettiğini ortaya çıkarır.

Allocation Tracking ile Xcode Instruments

iOS'ta, nesne oluşturma ve serbest bırakmayı izlemek için Instruments'ta Allocations şablonunu kullanın. Generations'ı etkinleştirin — eylemler arasında yığın anlık görüntüleri almanıza ve bellekte hangi nesnelerin kaldığını görmenize olanak tanır. Serbest bırakılmayan kalıcı nesneler, bellek birikiminin ve sonraki duraklamaların kaynağıdır.

Android'de JankStats API

JankStats, gerçek zamanlı olarak atlanan kare metriklerini toplayan bir Android kitaplığıdır. Her jank'ı geçerli senaryoya (örneğin, “liste kaydırma”, “ekran açma”) bağlayarak hangi belirli eylemin donmayı tetiklediğini anlamayı sağlar.

Android'de donmaları izlemek için JankStats entegrasyonu örneği:

kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var jankStats: JankStats

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        jankStats = JankStats.create(this.window.decorView) { frameData ->
            if (frameData.isJank()) {
                Log.w("Jank", "Duration=${frameData.durationMs}ms")
            }
        }
    }
}

Yavaş performansı ortadan kaldırma yöntemleri

Donmayı ortadan kaldırmak, her neden üzerinde hedefe yönelik çalışma gerektirir. Evrensel bir çözüm yoktur — belirli performans profillerinin analizi gerekir.

Paging 3 aracılığıyla sayfalama uygulaması

Bir liste 1000+ öğe içeriyorsa ve tümü aynı anda yükleniyorsa — bu garantili donmadır. Android'de Paging 3 ve iOS'ta NSFetchedResultsController, kullanıcı kaydırdıkça verileri bölümler halinde yükler. Kullanıcı yalnızca ilk 10–20 öğeyi görür; geri kalanı arka planda yüklenir.

SQL sorgularını ve indeksleri optimize etme

Room, Android Studio'daki Denetim Aracı aracılığıyla sorguları profillemeye olanak tanır: yürütme süresi, döndürülen satır sayısı ve sorgu planı görülebilir. WHERE ve ORDER BY sütunlarına indeks eklemek, sorgu süresini 300 ms'den 5 ms'ye düşürebilir. iOS'ta, Instruments'taki Core Data Profiler benzer bir kontrol gerçekleştirir.

Görevleri WorkManager'e aktarma

Arka plan senkronizasyonları, dosya indirmeleri, veri işleme — tüm bunlar WorkManager (Android) veya Background Tasks (iOS) aracılığıyla yürütülmelidir. Senkronizasyon UI iş parçacığında çalışırsa, uygulama yürütme sırasında donacaktır. WorkManager, pil ve ağ durumunun farkında olarak bir arka plan iş parçacığında yürütmeyi garanti eder.

Android'de WorkManager aracılığıyla arka plan senkronizasyonu örneği:

kotlin
class SyncWorker(context: Context, params: WorkerParameters)
    : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            Log.d("Sync", "Syncing data in background thread")
            syncData()
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

Geliştirme aşamasında donmayı önleme

Donma, verimli bellek ve iş parçacığı yönetimi ilkelerini izleyerek kodlama aşamasında önlenebilir.

AOT derlemesi için Baseline Profiles

Baseline Profiles, Android'in JIT yerine önceden (AOT) derlediği sınıflar ve yöntemler listesidir. Profil olmadan, her yeni ekran ilk açılışta derlenir ve 100–500 ms gecikmeye neden olur. Ana ekranlar için bir Baseline Profile hazırlayın ve baseline-profile-gradle-plugin aracılığıyla Gradle'da oluşturmayı etkinleştirin.

Sıcak yollarda ayırmaları en aza indirme

Sıcak yol, her karede yürütülen koddur: onBindViewHolder, draw, layoutSubviews. Bu yöntemlerde nesne oluşturmaktan kaçının: nesne havuzları kullanın, birleştirme yerine StringBuilder kullanın, biçimlendirilmiş dizeleri ve biçimlendiricileri önbelleğe alın. Her ekstra ayırma bir sonraki GC'yi yaklaştırır.

CI'da Baseline Profiles aracılığıyla profilleme

CI hattınıza bir liste kaydırma ve ekran açma senaryosuyla Macrobenchmark ekleyin. Bir eşik belirleyin: kare süresinin 99. yüzdelik dilimi 16 ms'yi geçmemelidir. Eşik aşılırsa — optimizasyon yapılana kadar yapı reddedilir.

  • Android — Baseline Profiles, Macrobenchmark, JankStats, penaltyDeath ile StrictMode
  • iOS — MetricKit, os_signpost, XCTMetric, Debug şemasında Main Thread Checker
  • Genel yaklaşım — düzenli profilleme, sıcak yollarda ayırmalara odaklanan kod incelemeleri

Sıkça sorulan sorular

Donma normal lag'dan nasıl farklıdır?

Lag, sabit bir gecikmedir (örneğin, her dokunuşta 200 ms). Donma aralıklıdır: uygulama normal çalışır, ardından aniden 1–3 saniye yavaşlar, sonra normale döner. Neden, GC duraklamaları veya senkron veritabanı sorguları gibi olay odaklı faktörlerdir.

Android'de GC duraklama sıklığı nasıl ölçülür?

Android Studio'da Memory Profiler'ı kullanın: Memory sekmesi GC olaylarını süreyle gösterir. Üretim izleme için, özel izlerle Firebase Performance Monitoring'i entegre edin. iOS'ta Malloc Debug'u etkinleştirin ve Instruments'ta ayırma nesillerini işaretleyin.

Ağ istekleri donmaya neden olabilir mi?

Dolaylı olarak — evet. Sunucu yanıtı gecikirse ve UI senkron olarak beklerse, uygulama donar. İstek asenkron olsa bile yanıt işleme UI iş parçacığında yapılırsa — bu da donmaya neden olur. Çözüm, coroutine'ler ve ilerleme göstergeleriyle asenkron işlemedir.

Kotlin Multiplatform performansı nasıl etkiler?

Yanlış kullanıldığında, KMP birlikte çalışabilirlik için aşırı sarmalayıcı nesneler üretebilir. iOS'ta bu, ayırma sıklığını ve dolayısıyla ARC duraklamalarını artırır. @ObjCName kullanın, expect/actual'ı optimize edin ve UI sıcak yollarından paylaşılan koda sık çağrılardan kaçının.

Android'de yığın boyutunu artırmak yardımcı olur mu?

android:largeHeap=”true” aracılığıyla yığını artırmak GC'yi geciktirir ancak ayırmaların nedenini ortadan kaldırmaz. GC sonunda çalıştığında, daha fazla nesnenin geçilmesi gerektiğinden duraklama daha uzun olacaktır. Çözüm, yığını genişletmek değil, ayırma sayısını azaltmaktır.

Özet

  • Donma, olay odaklı faktörlerden (GC duraklamaları, senkron sorgular, görüntü kod çözme) kaynaklanan aralıklı bir uygulama yavaşlamasıdır
  • Teşhis, Memory Profiler, Android'de JankStats ve iOS'ta Instruments'ta Allocation Tracking gerektirir
  • Ana nedenler — sık GC duraklamaları, sayfalama eksikliği, optimal olmayan SQL sorguları ve UI iş parçacığında senkron işleme
  • Çözüm — Paging 3, WorkManager, DB indeks optimizasyonu, görüntü küçültme ve ayırma minimizasyonu
  • Korunma — Baseline Profiles, Macrobenchmark, StrictMode, sıcak yol denetimiyle kod incelemeleri
  • Araçlar — üretim donma izleme için JankStats, Firebase Performance, MetricKit
  • Öneri: 99. kare yüzdelik diliminde 16 ms eşiğiyle CI'da düzenli Macrobenchmark çalıştırmaları uygulayın

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun