ڈویلپمنٹ میں جمود — جوہر، اسباب اور روک تھام

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

جمود (پھنسنا) ایک ایسی حالت ہے جس میں موبائل ایپلیکیشن طویل عرصے تک صارف کے کسی بھی عمل کا جواب دینا بند کر دیتی ہے۔ لیگ (سستی) اور گلچ (غلط رویہ) کے برعکس، جمود UI کو مکمل طور پر مسدود کر دیتا ہے: ٹچ پروسیس نہیں ہوتے، اینیمیشن رک جاتی ہے، اسکرین “جم جاتی ہے”۔ وجہ سنکرونس آپریشن کے ذریعے مرکزی تھریڈ کا مسدود ہونا، ملٹی تھریڈڈ کوڈ میں ڈیڈلاک، یا غیر معمولی طور پر طویل گاربیج کلیکشن ہے۔ Apple Main Thread Checker دستاویزات کے مطابق، iOS کے 40% سے زیادہ کریش رپورٹس مرکزی تھریڈ کی مسدودی سے متعلق ہیں۔ Android پر، ایسی ہی صورت حال ANR — سسٹم ڈائیلاگ “ایپ جواب نہیں دے رہی” — کی طرف لے جاتی ہے۔

اہم نکات

  • جمود — طویل عرصے کے لیے UI کا مکمل مسدود ہونا (سیکنڈ اور دسیوں سیکنڈ)، لیگ اور گلچ سے مختلف
  • بنیادی اسباب — I/O کے ذریعے مرکزی تھریڈ کا مسدود ہونا، تھریڈز کے درمیان ڈیڈلاک، لامتناہی لوپ اور طویل GC کے ساتھ میموری لیک
  • تشخیص میں iOS پر Main Thread Checker، Android پر ANR لاگز /data/anr/traces.txt اور تھریڈ ڈمپ کا تجزیہ شامل ہے
  • ازالہ — تمام ممکنہ طور پر طویل کارروائیوں کو بیک گراؤنڈ تھریڈز پر منتقل کرنا، Structured Concurrency کا استعمال اور UI تھریڈ میں synchronized سے گریز
  • روک تھام — StrictMode، Debug اسکیم میں Main Thread Checker، ڈیڈلاک کے لیے جامد تجزیہ اور ردعمل کے وقت کی پیمائش کرنے والے متواتر ٹیسٹ

موبائل ڈویلپمنٹ میں جمود کیا ہے

جمود (پھنسنا) موبائل ایپلیکیشن میں ایک ایسی حالت ہے جہاں ایپ کئی سیکنڈ یا اس سے زیادہ وقت تک ان پٹ ایونٹس پر کارروائی اور انٹرفیس کو اپ ڈیٹ کرنا بند کر دیتی ہے۔ تکنیکی طور پر، اس کا مطلب ہے کہ مرکزی تھریڈ مسدود ہے اور اگلی رن لوپ تکرار کو انجام نہیں دے سکتا۔

جمود، لیگ اور ANR کے درمیان فرق

لیگ 500 ms تک کی تاخیر ہے جہاں صارف سست محسوس کرتا ہے لیکن ایپ کام کرتی رہتی ہے۔ جمود 1 سیکنڈ سے دسیوں سیکنڈ تک رہتا ہے۔ Android پر ANR جمود کی ایک خاص صورت ہے جو 5 سیکنڈ سے زیادہ رہی اور سسٹم کے ذریعے پکڑی گئی۔ ہر جمود ANR کا باعث نہیں بنتا، لیکن ہر ANR سسٹم کے ذریعے دستاویزی جمود ہے۔

جمود کے نتائج

Android پر، 5 سیکنڈ سے زیادہ کا جمود ANR ڈائیلاگ کو متحرک کرتا ہے جو ایپ بند کرنے کی تجویز دیتا ہے۔ iOS پر، سسٹم میں واچ ڈاگ ہے — اگر ایپ 10–20 سیکنڈ تک ایونٹس کا جواب نہیں دیتی، واچ ڈاگ کوڈ 0x8badf00d (ate bad food) کے ساتھ عمل ختم کر دیتا ہے۔ صارف صرف ایپ کو اچانک ہوم اسکرین پر بند ہوتے دیکھتا ہے۔

Android اور iOS پر جمود کی وجوہات

کوئی بھی کارروائی جو 100 ms سے زیادہ لیتی ہے اور مرکزی تھریڈ پر چلائی جاتی ہے، ممکنہ طور پر جمود کا سبب بن سکتی ہے۔ آئیے مسدودی کے اہم ذرائع دیکھتے ہیں۔

UI تھریڈ میں سنکرونس I/O

بڑی فائل پڑھنا، بغیر غیر متزامن کے نیٹ ورک کی درخواست، SharedPreferences میں سنکرونس apply طریقہ اور پھر commit کے ذریعے ڈیٹا محفوظ کرنا — یہ تمام کارروائیاں مرکزی تھریڈ کو مسدود کرتی ہیں۔ Android پر، 10 MB کی فائل کو سنکرونس طور پر پڑھنے میں فلیش میموری کی رفتار کے لحاظ سے 200–500 ms لگ سکتے ہیں۔ iOS پر، completionHandler کے بغیر سنکرونس URLSession لوڈ سرور کے جواب کے وقت کے لیے UI کو مسدود کرتا ہے۔

ملٹی تھریڈڈ کوڈ میں ڈیڈلاک

جب دو تھریڈ ایک دوسرے کے پاس موجود وسائل کی منتظر ہوں تو ڈیڈلاک ہوتا ہے۔ موبائل ایپلیکیشنز میں، ایک عام منظر نامہ یہ ہے کہ تھریڈ A Lock1 کو لاک کرتا ہے اور Lock2 کا انتظار کرتا ہے، جبکہ تھریڈ B Lock2 کو لاک کرتا ہے اور Lock1 کا انتظار کرتا ہے۔ دونوں تھریڈ ہمیشہ کے لیے جم جاتے ہیں۔ اگر ان میں سے ایک مرکزی تھریڈ ہے تو ایپلیکیشن مکمل طور پر جم جاتی ہے۔

لامتناہی لوپ یا تکرار

منطق میں غلطی — مثال کے طور پر، باہر نکلنے کی شرط کے بغیر while(true) یا بنیادی کیس کے بغیر تکرار — مرکزی تھریڈ پر لامتناہی عملدرآمد کا باعث بنتی ہے۔ Android اسے 5 سیکنڈ کے بعد ANR کے ذریعے پکڑتا ہے، iOS — اسٹیک شاٹ کے ذریعے، جو لامتناہی طور پر دہرائے جانے والے کال اسٹیک کو کیپچر کرتا ہے۔

  • Android — بغیر بند کیے گئے Cursor، enqueue() کے بجائے execute() کے ذریعے سنکرونس درخواست، UI تھریڈ میں FileInputStream.read()
  • iOS — performSelectorOnMainThread:withObject:waitUntilDone:YES، NSURLConnection sendSynchronousRequest شروع کرنا، dataWithContentsOfURL کے ساتھ تصویر لوڈ کرنا
  • کراس پلیٹ فارم — مخصوص isolate کے بغیر Flutter compute، سنکرونس React Native NativeModule

جمود کی تشخیص کیسے کریں

جمود کی تشخیص کے لیے ایسے اوزار درکار ہیں جو مسدودی کے لمحے میں تمام تھریڈز کی حالت کو کیپچر کر سکیں۔

Android پر ANR لاگز

ہر ANR پر، Android سسٹم ایک فائل /data/anr/traces.txt محفوظ کرتا ہے جس میں ہر ایپ تھریڈ کا اسٹیک ڈمپ ہوتا ہے۔ اس فائل کا تجزیہ کرنا تشخیص کا بنیادی طریقہ ہے: main تھریڈ تلاش کریں اور دیکھیں کہ یہ کس طریقہ پر رکا ہے۔ اگر اسٹیک Thread.sleep، InputStream.read یا Lock.lock پر ختم ہوتا ہے — وجہ مل گئی۔

iOS پر اسٹیک شاٹ

Xcode ایپ کے جم جانے پر (SIGSTOP سگنل) اسٹیک شاٹ — تمام تھریڈ اسٹیک کا سنیپ شاٹ — لے سکتا ہے۔ اسکیم میں “Logging” → “Include Stackshot Logs” کو فعال کریں۔ کوڈ 0x8badf00d کے ساتھ کریش پر، Devices & Simulators سے کریش لاگ نکالیں اور پھنسے ہوئے اسٹیک کے ساتھ com.apple.main-thread تلاش کریں۔

Xcode میں Main Thread Checker

Main Thread Checker ایپ چلنے کے دوران بیک گراؤنڈ تھریڈز سے UIKit کالز کو خود بخود پکڑتا ہے۔ اسے اسکیم میں فعال کریں (Diagnostics → Main Thread Checker)۔ ہر انتباہ جمود کا ممکنہ سبب ہے، خاص طور پر اگر یہ نیٹ ورک کی درخواست کے completionHandler closure میں ہوتا ہے۔

Android پر StrictMode کے ذریعے مسدودی کا پتہ لگانے کی مثال:

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .penaltyLog()
            .build())
        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyDeath()
            .build())
    }
}

UI مسدودی کو ختم کرنے کے طریقے

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

کوروٹین کے ساتھ ساختی ہم وقتی

Kotlin Coroutines viewModelScope.launch(Dispatchers.IO) کے ساتھ اس بات کی ضمانت دیتے ہیں کہ نیٹ ورک آپریشن یا ڈیٹا بیس ریڈ بیک گراؤنڈ تھریڈ میں انجام پائیں۔ Dispatchers.Main صرف UI اپ ڈیٹس کے لیے استعمال ہوتا ہے۔ اہم: تمام suspend فنکشن ساختی ہونے چاہئیں — چائلڈ کوروٹین والدین کے منسوخ ہونے پر منسوخ ہو جاتے ہیں، تھریڈ لیک کو روکتے ہیں۔

iOS پر غیر متزامن قطاریں

Grand Central Dispatch بیک گراؤنڈ کاموں کے لیے DispatchQueue.global(qos: .userInitiated) اور UI اپ ڈیٹس کے لیے DispatchQueue.main.async کے ساتھ معیاری پیٹرن ہے۔ مرکزی قطار میں sync() سے گریز کریں — یہ یقینی ڈیڈلاک ہے۔ MainActor کے ذریعے مرکزی تھریڈ پر خودکار واپسی کے ساتھ زیادہ پڑھنے کے قابل غیر متزامن کوڈ کے لیے async/await (Swift 5.5+) استعمال کریں۔

UI تھریڈ میں synchronized سے گریز

مرکزی تھریڈ پر Kotlin میں synchronized بلاکس اور Swift میں @synchronized خطرناک ہیں: اگر کسی دوسرے تھریڈ نے پہلے ہی یہ لاک حاصل کر لیا ہے تو مرکزی تھریڈ انتظار میں جم جائے گا۔ لاک کے بجائے ایٹمی اقسام (AtomicInteger، Swift میں ایٹمی خصوصیات) یا سیریل قطاریں استعمال کریں۔

Android پر کوروٹین کے ساتھ غیر متزامن ڈیٹا لوڈنگ کی مثال:

kotlin
class DataViewModel : ViewModel() {
    private val _data = MutableStateFlow<List<Item>>(emptyList())
    val data: StateFlow<List<Item>> = _data.asStateFlow()

    fun loadData() {
        viewModelScope.launch(Dispatchers.IO) {
            val result = fetchFromNetwork()
            _data.emit(result)
        }
    }
}

ڈویلپمنٹ مرحلے میں جمود کی روک تھام

اوزار، فن تعمیر کے اصول اور کوڈ ریویو کے عمل کا امتزاج منظم طریقے سے جمود کو روکنے میں مدد دیتا ہے۔

penaltyDeath کے ساتھ StrictMode

تھریڈ پالیسیوں کے لیے StrictMode کو penaltyDeath کے ساتھ ترتیب دیں — اس سے مرکزی تھریڈ پر نیٹ ورک کال یا ڈسک I/O پکڑے جانے پر فوری ایپ کریش ہو جائے گا۔ ڈویلپر مسئلہ کو نظر انداز نہیں کر سکے گا۔ پروڈکشن بلڈز میں، بغیر کریش کے اعدادوشمار جمع کرنے کے لیے penaltyLog استعمال کریں۔

Debug اسکیم میں Main Thread Checker

iOS پر، Debug اسکیم میں Main Thread Checker کو فعال کریں اور CI کو اس آپشن کے ساتھ ٹیسٹ چلانے کے لیے ترتیب دیں۔ اگر ٹیسٹ میں بیک گراؤنڈ تھریڈ سے UIKit کال ہے — تو اسے ناکام ہونا چاہیے۔ TestFlight پر بھیجنے سے پہلے مسئلہ کی شناخت کرنے کا یہ واحد قابل اعتماد طریقہ ہے۔

ملٹی تھریڈنگ جانچ کے ساتھ ہم مرتبہ جائزہ

کوڈ ریویو کے عمل میں ایک لازمی نکتہ شامل کریں: تصدیق کریں کہ کوئی بھی نیٹ ورک کال، فائل آپریشن، ڈیٹا بیس تک رسائی یا بھاری حساب بیک گراؤنڈ تھریڈ میں چلتا ہے۔ ڈیڈلاک کو جامد تجزیہ کاروں سے پکڑا جا سکتا ہے: Facebook کا Infer اور Xcode کا Thread Safety Checker رن ٹائم سے پہلے ممکنہ لاک تلاش کر لیتے ہیں۔

  • Android — StrictMode, Infer, Android Lint Multithread, viewModelScope کے ساتھ Kotlin Coroutines
  • iOS — Main Thread Checker, TSAN (Thread Sanitizer), Xcode Analyze, MainActor کے ساتھ Swift async/await
  • کراس پلیٹ فارم — Flutter compute isolate, requestAnimationFrame کے ساتھ React Native interaction manager

اکثر پوچھے گئے سوالات

جمود اور ANR میں کیا فرق ہے؟

ANR (Application Not Responding) ایک Android سسٹم نوٹیفکیشن ہے جو مرکزی تھریڈ کے 5 سیکنڈ سے زیادہ جم جانے پر ظاہر ہوتا ہے۔ جمود ایک وسیع تر تصور ہے: کسی بھی مدت کا کوئی بھی UI مسدود ہونا۔ iOS میں ANR نہیں ہے، لیکن 10–20 سیکنڈ ٹائم آؤٹ کے ساتھ ایک واچ ڈاگ ہے۔

Android پر traces.txt کیسے پڑھیں؟

فائل /data/anr/traces.txt پر واقع ہے۔ رسائی کے لیے روٹ رسائی یا adb shell درکار ہے: روٹ اختیارات کے ساتھ adb shell cat /data/anr/traces.txt \> traces.txt چلائیں۔ اسٹیک میں “main” تھریڈ تلاش کریں — آخری بلایا گیا طریقہ مسدودی کی وجہ بتاتا ہے۔

iOS پر ایپ کیوں جمتی ہے لیکن کریش نہیں ہوتی؟

اگر جمود 10 سیکنڈ سے کم رہے تو واچ ڈاگ فعال نہیں ہوتا اور ایپ مسدود کرنے والی کارروائی مکمل ہونے تک بس “پھنسی” رہتی ہے۔ صارف کریش نہیں دیکھتا لیکن مایوسی محسوس کرتا ہے۔ ایسے معاملات کا پتہ لگانے کے لیے، اپنی مرضی کے عملدرآمد کے وقت کے نشانات کے ساتھ MetricKit استعمال کریں۔

جمود کے خلاف ایپ کی جانچ کیسے کریں؟

UI ٹیسٹ استعمال کریں اس تصدیق کے ساتھ کہ اسکرین 1 سیکنڈ سے کم میں کھلتی ہے۔ ٹیپ اور اگلی اسکرین کے ظاہر ہونے کے درمیان وقت کی پیمائش CI میں شامل کریں۔ Android پر، غیر متزامن کارروائیوں کے انتظار کے لیے IdlingResource کے ساتھ Espresso استعمال کریں۔ iOS پر، لوڈنگ وقت کی جانچ کے لیے XCTWaiter کے ساتھ XCTest استعمال کریں۔

کیا SwiftUI جمود کا سبب بن سکتا ہے؟

SwiftUI خود جمود کا سبب نہیں بنتا، لیکن body پراپرٹی میں پیچیدہ حسابات سبب بنتے ہیں۔ اگر بھاری کارروائیوں کی وجہ سے body کا حساب 500 ms لیتا ہے تو UI جم جاتا ہے۔ حل یہ ہے کہ حسابات کو Task.detached میں منتقل کریں اور @State کو مرکزی اداکار پر غیر متزامن طور پر اپ ڈیٹ کریں۔

خلاصہ

  • جمود — سیکنڈ سے دسیوں سیکنڈ تک UI کا مکمل مسدود ہونا، مرکزی تھریڈ کی مسدودی، ڈیڈلاک یا لامتناہی لوپ کی وجہ سے
  • تشخیص — Android پر /data/anr/traces.txt، iOS پر Stackshot اور Main Thread Checker
  • بنیادی اسباب — سنکرونس I/O، تھریڈز کے درمیان ڈیڈلاک، لامتناہی تکرار، طویل GC
  • ازالہ — صحیح ڈسپیچر کے ساتھ کوروٹین، MainActor کے ساتھ async/await، تمام I/O کارروائیوں کو بیک گراؤنڈ تھریڈز پر منتقل کرنا
  • روک تھام — penaltyDeath کے ساتھ StrictMode، Main Thread Checker، ڈیڈلاک کے لیے جامد تجزیہ (Infer, TSAN)
  • Android پر جمود > 5 s = ANR؛ iOS پر > 10–20 s = واچ ڈاگ کریش (0x8badf00d)
  • سفارش: Debug اسکیم میں Thread Sanitizer کو فعال کریں اور ڈیٹا ریس اور ڈیڈلاک کا پتہ لگانے کے لیے CI کو TSAN کے ساتھ ٹیسٹ چلانے کے لیے ترتیب دیں

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

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

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

مزید پڑھیں