ڈیولپمنٹ میں پھنسنا — یہ کیا ہے، اسباب اور بہترین کے طریقے

مصنف: IT Sectr اشاعت: 2026-07-28 مطالعے کا وقت: 8 منٹ

پھنسنا صارف کی طرف سے اس حالت کی وضاحت ہے جب کوئی موبائل ایپ آﮦستہ اور غیر مستقل طور پر کام کرتا ہے: کبھی طور پر جواب دیتا ہے، کبھی اچانک چند سیکنڈ کے لیے جم جاتا ہے۔ تکنیکی سیاق میں، «پھنسنا» کا مطلب ہے بار بار GC توقفوں، مرکزی ثریڈ کے متضاد کارروائیوں سے بلاک ہونے اور غیر موزوں ڈیٹا ساختوں کے کارن لگز اور مائیکرو فریز کا مرکب ہے۔ Android Performance Benchmarking Guide کے مطابق، جوابی وقت کو 300 میلی سیکنڈ سے 100 میلی سیکنڈ کرنے سے صارف برقراری میں 25% اضافہ ہوتا ہے۔ پھنسنے کی تشخیص کے لیے CPU اور میموری پروفائلنگ کے ساتھ کوڑا کٹھائی کی تکرار کا تجزیۓ درکار ہے۔

اہم نکات

  • پھنسنا ایپ کی ایک وقفی سستگی ہے، جو عام کارکردگی کے ساتھ متبادل ہوتی ہے
  • بنیادی وجوہات — بار بار GC توقف، UI ثریڈ پر متضاد کارروائیاں، صفحہ بندی کے بغیر ایڈاپٹرز میں بڑا ڈیٹا حجم
  • تشخیص کے لیے رکاوٹیں چھوٹنے کے لیے CPU Profiler اور GC تکرار اور دیرانی کا تجزیۓ کرنے کے لیے Memory Profiler درکار ہے
  • حل میں صفحہ بندی (Paging 3) نفاذ، Room کے ذریعے SQL کوئریز کی بہترینی، اور بھاری کاموں کو WorkManager میں منتقل کرنا شامل ہے
  • بچاو — Benchmark Baseline Profiles، AOT ترتیب، گرم کوڈ راستوں میں تخصیصات کی کم سے کم

موبائل ڈیولپمنٹ میں «پھنسنا» کا کیا مطلب ہے

پھنسنا ایک غیر سرکاری اصطلاح ہے جو صارف شخصی طور پر آﮦستہ ایپ کارکردگی کی وضاحت کے لیے استعمال کرتے ہیں۔ لگ کے برعکس، جو مستقل تاخیر کے طور پر ظاہر ہوتا ہے، پھنسنا بقاعدگی جمنے پر مشتمل ہے: ایپ کئی سیکنڈ تک بہترین طریقے سے کام کر سکتا ہے اور پھر 1–3 سیکنڈ کے لیے «سوچنا» شروع کر سکتا ہے۔

رجحان کی تکنیکی وضاحت

پروفائلنگ کے زاویۓ سے، پھنسنا چوٹی دیر کے ساتھ چھوٹے ہوئے فریمز (jank) کے ایک سلسلے کے طور پر ظاہر ہوتا ہے جو 100 میلی سیکنڈ سے تجاوز کرتی ہیں۔ FPS گراف پر، یہ تیز گراوٹں کے طور پر دیکھائی دیتا ہے: 60 → 20 → 55 → 10 فریم فی سیکنڈ۔ یکساں کم FPS والے لگ کے برعکس، پھنسنے میں واضح تغیر پذیری ہوتی ہے۔

صارف کا ادراک

جب ایپ پھنستا ہے، صارف سستگی کی وجہ سمجھ نہیں پاتا: سکرین آسانی سے اسکرول ہو سکتی ہے اور پھر اچانک ایک سیکنڈ کے لیے رک سکتی ہے۔ یہ مایوسی کا سبب بنتا ہے اور ایپ پر اعتماد کم کرتا ہے۔ Google کے مطابق، 53% صارف کسی سائٹ یا ایپ کو چھوڑ دیتے ہیں اگر لوڈنگ میں 3 سیکنڈ سے زیادہ وقت لگتا ہے۔

ایپس میں اچانک سستگی کے اسباب

پھنسنے کی وقفی نیچر اس بات کی طرف اشارہ کرتی ہے کہ مسئلہ مسلسل بہتر بار کے بجائے واقعات پر مبنی عوامل کے کارن ہوتا ہے۔ آئیے معمولی مناظر کا جائزہ کرتے ہیں۔

آبجیکٹ تخصیص کے دوران GC توقف

Android پر، ART ران ٹائم میں، کوڑا کٹھائی ایپ کے تمام ثریڈز کو روک دیتی ہے۔ اگر کوڈ بہت سے عارضی آبجیکٹ بناتا ہے — مثال کے طور پر، ہر onBindViewHolder کال پر جڑ کے ذریعے ایک نیا String بنانا — GC زیادہ چلتا ہے۔ ہیپ کے سائز اور آبجیکٹ نسل پر منحصر کرتے ہوئے ایک توقف 5–50 میلی سیکنڈ تک رہ سکتا ہے۔ صارف اسے اچانک «سوچنے» کے طور پر محسوس کرتا ہے۔

UI ثریڈ پر متضاد SQL کوئریز

Android پر Room اور iOS پر Core Data غیر متضاد کوئریز کی حمایت کرتے ہیں، لیکن ڈیولپر آکسر سادگی کے لیے getValue() کو کھینچتے ہیں یا runBlocking کے ذریعے کوئریز چلاتے ہیں۔ 10,000 قطاروں کی ایک ٹیبل پر جوائن کے ساتھ ایک بھاری SELECT میں 200–500 میلی سیکنڈ لگ سکتے ہیں، اس دوران UI کو مکمل طور پر بلاک کر دیتے ہیں۔

پیمانے کے بغیر تصویر کا ڈیکوڈنگ

ایک کیمرہ تصویر (12 MP, 4000x3000 پکسل) کو بغیر پیمانے کے لوڈ کرنے میں Bitmap ڈیکوڈنگ کے لیے 200 میلی سیکنڈ تک لگ سکتا ہے۔ اگر تصاویر غیر متضاد طور پر لیکن محدود ثریڈ پول کے بغیر لوڈ کی جاتی ہیں، تو 5–6 ڈیکوڈز کو بک ساتھ چلانے سے CPU بہتر جا سکتا ہے، جیسسے منتقل ہونے والی سستگیاں پیدا ہو سکتی ہیں۔

  • Android — لوپ میں سٹرنگ جڑ کرنا، گرم راستوں میں آبجیکٹ بنانا، inSampleSize کے بغیر Bitmap
  • iOS — بہت سارے آبجیکٹوں کے ساتھ آٹوریلیز پولز، پیمانے کے بغیر imageWithContentsOfFile، متضاد URLSession
  • کروس پلیٹ فارم — UI ثریڈ پر JSON پارسنگ، سرور کے جواب کا انتظار کرتے ہوئے مرکزی ثریڈ پر ڈیٹا لوڈ کرنا

Android اور iOS پر جمنے کی تشخیص کیسے کریں

وقفی سستگیوں کی تشخیص مسلسل لگزوں کی تشخیص سے زیادہ مشکل ہے کیونکہ ہر دفعہ چلانے پر مسئلہ دوبارہ پیدا نہیں ہو سکتا۔ ایک طویل مدت میں شماریات جمع کرنا ضروری ہے۔

GC واقعات کی ریکارڈنگ کے ساتھ Memory Profiler

Android Studio Memory Profiler صرف میموری استعمال ہی نہیں بلکہ GC واقعات بھی دیکھاتا ہے: تکرار، قسم (Concurrent, Full)، دیرانی۔ اگر خاموشی کی حالت میں GC ہر 5 سیکنڈ میں ایک بار سے زیادہ ہوتا ہے — یہ ضرورت سے زیادہ تخصیص کی نشانی ہے۔ پھنسنے کے لمحے هیپ ڈانپ لینے سے پتا چلتا ہے کہ کون سے آبجیکٹ میموری پر قابض ہیں۔

Allocation Tracking کے ساتھ Xcode Instruments

iOS پر، آبجیکٹ تخلیق اور آزادی کو ٹریک کرنے کے لیے Instruments میں Allocations ٹیمپلیٹ استعمال کریں۔ Generations کو فعال کریں — یہ کارروائیوں کے درمیان هیپ کی اسناپ شاٹس لینے اور دیکھنے کی اجازت دیتے ہیں کہ کون سے آبجیکٹ میموری میں رہ گئے ہیں۔ آزاد نہ ہونے والے مستقل آبجیکٹ میموری جمع ہونے اور بعد میں توقفوں کا ذریعہ بنتے ہیں۔

Android پر JankStats API

JankStats ایک Android لائبریری ہے جو حقیقی وقت میں چھوٹے ہوئے فریم میٹرکز جمع کرتی ہے۔ یہ ہر jank کو موجودہ منظر (مثال کے طور پر، “لیسٹ اسکرولنگ”، “سکرین کھولنا”) سے منسوب کرتی ہے، جیسسے یہ سمجھا جا سکتا ہے کہ کون سا مخصوص عمل پھنسنے کو متحرک کرتا ہے۔

Android پر جمنے کو ٹریک کرنے کے لیے JankStats کے انضمام کی مثال:

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")
            }
        }
    }
}

سستہ کارکردگی کو ختم کرنے کے طریقے

پھنسنے کو ختم کرنے کے لیے ہر وجہ پر نشانہ دار کام کی ضرورت ہے۔ کئی آلی عام حل نہیں ہے — مخصوص کارکردگی کے پروفائل کا تجزیۓ درکار ہے۔

Paging 3 کے ذریعے صفحہ بندی کا نفاذ

اگر ایک لیسٹ میں 1000+ آئٹم ہوں اور سب ایک ساتھ لوڈ کیے جاتے ہیں — یہ یقینی پھنسنا ہے۔ Android پر Paging 3 اور iOS پر NSFetchedResultsController صارف کو اسکرول کرنے پر ڈیٹا کو حصە میں لوڈ کرتے ہیں۔ صارف صرف پہلے 10–20 آئٹم دیکھتا ہے؛ باقی پس منظر میں لوڈ ہوتا ہے۔

SQL کوئریز اور انڈیکسز کی بہترینی

Room Android Studio میں معائنہ کے اوزار کے ذریعے کوئریز کی پروفائلنگ کی اجازت دیتا ہے: عملدرآمدی کا وقت، واپس کی گئی قطاروں کی تعداد اور کوئری کا منصوبہ نظر آتا ہے۔ WHERE اور ORDER BY کی کلموں پر انڈیکس شامل کرنے سے کوئری کا وقت 300 میلی سیکنڈ سے 5 میلی سیکنڈ تک کم ہو سکتا ہے۔ iOS پر، Instruments میں Core Data Profiler ایسی ہی جانچ کرتا ہے۔

کاموں کو WorkManager میں منتقل کرنا

پس منظر کی هم آہنگیاں، فائل ڈاؤن لوڈ، ڈیٹا پروسیسنگ — یہ سب WorkManager (Android) یا Background Tasks (iOS) کے ذریعے کرنا چاہیے۔ اگر ہم آہنگی UI ثریڈ پر چلتی ہے، تو ایپ عملدرآمدی کے دوران پھنسے گا। WorkManager بیٹری اور نیٹورک کی حالت سے آگاہی کے ساتھ پس منظر کے ثریڈ پر عملدرآمدی کی گارنٹی دیتا ہے۔

Android پر WorkManager کے ذریعے پس منظر ہم آہنگی کی مثال:

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()
        }
    }
}

ترقیاتی مرحلے پر پھنسنے سے بچاو

موزوں میموری اور ثریڈ انتظام کے اصولوں پر عمل کرتے ہوئے کوڈنگ کے مرحلے پر ہی پھنسنے سے بچا جا سکتا ہے۔

AOT ترتیب کے لیے Baseline Profiles

Baseline Profiles ان کلاسوں اور میتھڈز کی ایک فہرست ہے جنہیں Android JIT کے بجائے پہلے سے (AOT) ترتیب دیتا ہے۔ پروفائل کے بغیر، ہر نئی سکرین پہلی دفعہ کھولنے پر ترتیب پاتی ہے، جسسے 100–500 میلی سیکنڈ کی تاخیر ہوتی ہے۔ اہم سکرینز کے لیے ایک Baseline Profile تیار کریں اور baseline-profile-gradle-plugin کے ذریعے Gradle میں جینریشن فعال کریں۔

گرم راستوں میں تخصیصات کو کم سے کم کرنا

گرم راستہ وہ کوڈ ہے جو ہر فریم پر عملدرآمد ہوتا ہے: onBindViewHolder, draw, layoutSubviews۔ ان میتھڈز میں آبجیکٹ بنانے سے گریز کریں: آبجیکٹ پول استعمال کریں، جڑ کی جگہ StringBuilder استعمال کریں، فارمیٹ شدہ سٹرنگز اور فارمیٹر کو کیش کریں۔ ہر ضرورت سے زائد تخصیص اگلے GC کو قریب لاتا ہے۔

CI میں Baseline Profiles کے ذریعے پروفائلنگ

اپنے CI پائپ لائن میں لیسٹ اسکرولنگ اور سکرین کھولنے کے منظر کے ساتھ Macrobenchmark شامل کریں۔ ایک حد مقرر کریں: فریم وقت کا 99واں فیصد سائز 16 میلی سیکنڈ سے تجاوز نہ کرے۔ حد سے تجاوز کرنے پر — بہترینی تک بلڈ مسترد کر دیا جاتا ہے۔

  • Android — Baseline Profiles, Macrobenchmark, JankStats, penaltyDeath کے ساتھ StrictMode
  • iOS — MetricKit, os_signpost, XCTMetric, Debug اسکیم میں Main Thread Checker
  • عام طریقہ کار — باقاعدگی پروفائلنگ، گرم راستوں میں تخصیصات پر مرکوز کوڈ کا جائزہ

اکثر پوچے جانے والے سوالات

پھنسنا عام لگ سے کیسے مختلف ہے؟

لگ ایک مستقل تاخیر ہے (مثال کے طور پر، ہر ٹیپ پر 200 میلی سیکنڈ)۔ پھنسنا وقفی ہے: ایپ طور پر کام کرتا ہے، پھر اچانک 1–3 سیکنڈ کے لیے سست ہو جاتا ہے، پھر عام ہو جاتا ہے۔ وجہ GC توقفوں یا ڈیٹابیس کی متضاد کوئریز جیسے واقعات پر مبنی عوامل ہے۔

Android پر GC توقفوں کی تکرار کیسے ماپیں؟

Android Studio میں Memory Profiler استعمال کریں: Memory ٹاب GC واقعات کو دیرانی کے ساتھ دیکھاتا ہے۔ پروڈکشن مونیٹرنگ کے لیے، کسٹم ٹریس کے ساتھ Firebase Performance Monitoring کو مضمون کریں۔ iOS پر، Malloc Debug فعال کریں اور Instruments میں تخصیص نسلوں کو نشان کریں۔

کیا نیٹورک درخواستیں پھنسنے کا سبب بن سکتی ہیں؟

غیر مباہشہ طور پر — ہاں۔ اگر سرور کا جواب دیر سے آتا ہے اور UI متضاد طور پر اسکا انتظار کرتی ہے، تو ایپ جم جاتا ہے۔ اگر درخواست غیر متضاد ہے لیکن جواب کی پروسیسنگ UI ثریڈ پر کی جاتی ہے — تو یہ بھی پھنسنے کا سبب بنے گا। حل کوروٹین اور پیشرفتی کے اشاروں کے ساتھ غیر متضاد پروسیسنگ ہے۔

Kotlin Multiplatform کارکردگی کو کیسے متاثر کرتا ہے؟

غلط طریقے سے استعمال کرنے پر، KMP باھمی عمل پذیری کے لیے ضرورت سے زائد ریپر آبجیکٹ تیار کر سکتا ہے۔ iOS پر، یہ تخصیص کی تکرار اور نتیجہ میں ARC توقفوں کو بڑھاتا ہے۔ @ObjCName استعمال کریں، expect/actual کو بہتر کریں اور UI گرم راستوں سے مشترک کوڈ کی بار بار کالوں سے گریز کریں۔

کیا Android پر ہیپ کا حجم بڑھانے سے مدد ملتی ہے؟

android:largeHeap=”true” کے ذریعے ہیپ بڑھانا GC میں تاخیر کرتا ہے لیکن تخصیص کی وجہ کو ختم نہیں کرتا۔ جب GC بالآخر چلتا ہے، تو توقف لمبا ہوگا کیونکہ مزید آبجیکٹوں کو پار کرنا پڑے گا। حل ہیپ کو وسیع کرنا نہیں، بلکہ تخصیص کی تعداد کو کم کرنا ہے۔

خلاصہ

  • پھنسنا واقعات پر مبنی عوامل (GC توقف، متضاد کوئریز، تصویر کا ڈیکوڈنگ) کے کارن هونے والی وقفی ایپ سستگی ہے
  • تشخیص کے لیے Memory Profiler، Android پر JankStats اور iOS پر Instruments میں Allocation Tracking درکار ہے
  • بنیادی وجوہات — بار بار GC توقف، صفحہ بندی کی کمی، غیر موزوں SQL کوئریز اور UI ثریڈ پر متضاد پروسیسنگ
  • حل — Paging 3، WorkManager، DB انڈیکس بہترینی، تصویر کا پیمانہ بڈھانا اور تخصیص کی کم سے کمی
  • بچاو — Baseline Profiles، Macrobenchmark، StrictMode، گرم راستوں کی جانچ کے ساتھ کوڈ کا جائزہ
  • اوزار — پروڈکشن پھنسنے کی نگرانی کے لیے JankStats، Firebase Performance، MetricKit
  • سفارش: 99وں فریم فیصد سائز پر 16 میلی سیکنڈ کی حد کے ساتھ CI میں باقاعدگی Macrobenchmark ران نفاذ کریں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں