میموری لیک اور پھولنا — یہ کیا ہے، اسباب اور بچاؤ کے طریقے

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

میموری لیک — موبائل ڈویلپمنٹ میں سب سے مشکل مسائل میں سے ایک ہے۔ ایپ کا میموری استعمال مسلسل بڑھتا رہتا ہے جب تک کہ یہ OS کے مقرر کردہ حد تک نہ پہنچ جائے، جس کے بعد OutOfMemoryError یا جبری خاتمہ ہوتا ہے۔ Square Engineering کے مطابق، تقریباً 40% Android ایپس میں کم از کم ایک میموری لیک ہوتی ہے جو صرف پروفائلنگ کے ذریعے دریافت کی جا سکتی ہے۔ آئیے اسباب اور میموری بڑھنے سے روکنے کے طریقوں کا جائزہ لیتے ہیں۔

اہم نکات

  • GC رسائی — اگر روٹ سیٹ سے فعال حوالہ موجود ہو تو آبجیکٹ حذف نہیں ہوتا
  • Activity یا Context کے جامد حوالہ جات — Android میں لیک کی سب سے عام وجہ
  • LeakCanary — Android میں خودکار لیک کھوج کا معیاری آلہ
  • WeakReference — ان حوالوں کا حل جو کوڑا کرکٹ جمع کرنے میں رکاوٹ نہیں بننے چاہئیں
  • Lifecycle-aware اجزاء — ویو تباہ ہونے پر خود بخود سبسکرپشن منسوخ کر دیتے ہیں

میموری لیک اور ایپ کا پھولنا کیا ہے؟

میموری لیک — ایک صورت حال جہاں ایک آبجیکٹ جو اب ایپ کے لیے ضروری نہیں ہے، ہیپ میں برقرار رہتا ہے کیونکہ GC روٹ سیٹ سے ایک فعال حوالہ اب بھی اس کی طرف اشارہ کر رہا ہے۔ کوڑا کرکٹ جمع کرنے والا ایسے آبجیکٹ کو زندہ سمجھتا ہے اور اسے ہٹاتا نہیں۔

میموری پھولنا — ایک وسیع تر مسئلہ جہاں ایپ اپنے موجودہ کاموں کو انجام دینے کے لیے ضرورت سے زیادہ میموری استعمال کرتی ہے۔ اسباب: ضرورت سے زیادہ کیشنگ، آبجیکٹ کی نقل، غیر موزوں ڈیٹا ڈھانچے، اور ہیپ کی بکھراوٹ۔

Android میں، ہر ایپ کو ایک محدود ہیپ مختص کیا جاتا ہے (عام طور پر ڈیوائس اور OS ورژن کے لحاظ سے 64–512 MB)۔ iOS میں، حد کم سخت ہے، لیکن حد کے قریب پہنچنے پر سسٹم میموری وارننگ بھیجتا ہے۔

خصوصیتAndroidiOS
ہیپ کی حد64–512 MB (ڈیوائس پر منحصر)ضمنی (سسٹم)
کوڑا کرکٹ جمع کرناART (بیک وقت، کمپیکٹ)ARC (خودکار حوالہ گنتی)
لیک کا طریقہ کارGC روٹ حوالہ جاتبرقرار رکھنے کے چکر (مضبوط حوالہ چکر)
نتیجہOutOfMemoryErrorمیموری وارننگ → خاتمہ

Facebook Engineering Blog کے مطابق، میموری لیک موبائل ایپس میں تقریباً ~15% کریش رپورٹس کا سبب بنتی ہیں۔ Android میں، میموری کم ہونے پر بار بار GC رکنے کی وجہ سے ANR بھی شامل ہو جاتے ہیں۔

Android اور iOS میں عام میموری لیک پیٹرن

Activity کا جامد حوالہ — ایک کلاسک Android لیک۔ اگر کوئی جامد فیلڈ یا سنگلٹن Activity کا حوالہ رکھتا ہے، تو singleton زندہ رہنے تک finish() کے بعد بھی GC اسے جمع نہیں کرے گا۔ Activity ایک بھاری آبجیکٹ ہے جس میں ویو کا درجہ بندی، وسائل اور Context شامل ہوتے ہیں۔

kotlin
object LeakHolder {
    var activityRef: Activity ?= null // leak: static reference to Activity
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle ?= null) {
        super.onCreate(savedInstanceState)
        LeakHolder.activityRef = this // ❌ MainActivity will never be GC'd
    }
}

گمنام کلاسز اور لیمبڈا — بیرونی کلاس کا ایک حوالہ واضح طور پر رکھتے ہیں۔ اگر Runnable یا Callback کسی بیرونی سروس کو بھیجا جائے اور Activity تباہ ہو جائے، تو گمنام کلاس کا آبجیکٹ ابھی بھی قطار میں رہتا ہے اور Activity کو کوڑا کرکٹ میں جمع ہونے سے روکتا ہے۔

  • Handler تاخیر کے ساتھ — اگر Activity تباہ ہو جائے لیکن Handler.postDelayed ابھی عمل میں نہ آیا ہو، تو Activity لیک ہو جاتی ہے
  • Thread اور AsyncTask — اسکرین گھمانے پر، Activity دوبارہ بنتی ہے جبکہ پرانا Thread پرانی Activity کا حوالہ رکھتا ہے
  • Retrofit/Callback — گمنام Callback پریزینٹر یا فریگمنٹ کا حوالہ رکھتا ہے
  • مشاہدہ کرنے والے — onDestroy پر بغیر منسوخی کے LiveData یا RxJava سبسکرپشنز

iOS میں اصل مسئلہ برقرار رکھنے کے چکر ہیں: دو آبجیکٹ ایک دوسرے کے مضبوط حوالہ جات رکھتے ہیں اور ARC کسی کے لیے بھی حوالہ شمار صفر نہیں کر سکتا۔ عام مثال: ایک closure جو self کو مضبوطی سے پکڑتا ہے، اور self جو closure کا حوالہ رکھتا ہے۔

میموری لیک کا پتہ کیسے لگائیں؟

LeakCanary — Android میں خودکار لیک کھوج کے لیے Square کی لائبریری۔ Activity یا Fragment تباہ ہونے کے بعد، یہ چیک کرتی ہے کہ آبجیکٹ GC نے جمع کیا یا نہیں۔ اگر نہیں، تو یہ ہیپ ڈمپ لیتی ہے اور لیک ٹریس دکھاتی ہے۔

kotlin
// LeakCanary 2.x — auto-integration via Application
class ExampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // LeakCanary auto-installs in debug build
        // via ContentProvider — zero code setup
    }
}

// Force check invocation
AppWatcher.objectWatcher.watch(watchedObject, "leak description")

Android Studio Profiler — ریئل ٹائم میموری مانیٹرنگ کے لیے بلٹ ان ٹول۔ یہ ہیپ ڈمپ ریکارڈ کرنے، مشکوک آبجیکٹ (Retained Size > 1 MB) تلاش کرنے اور ہر آبجیکٹ تک GC روٹ پاتھ ٹریس کرنے کی اجازت دیتا ہے۔

iOS کے لیے Xcode Memory Graph Debugger استعمال کریں۔ یہ میموری میں آبجیکٹ گراف کو دیکھتا ہے، برقرار رکھنے کے چکر دکھاتا ہے اور فوری طور پر سرکلر حوالوں کا پتہ لگانے کی اجازت دیتا ہے۔ طویل مدتی مانیٹرنگ کے لیے Instruments > Allocations بھی دستیاب ہے۔

روک تھام کی حکمت عملی

WeakReference — ان حوالوں کے لیے بنیادی طریقہ کار جو کوڑا کرکٹ جمع کرنے میں رکاوٹ نہیں بننے چاہئیں۔ اگر GC کسی آبجیکٹ کو جمع کرنے کا فیصلہ کرتا ہے، تو WeakReference null لوٹاتا ہے۔ یہ کال بیکس، سننے والوں اور بیک گراؤنڈ تھریڈز سے UI اجزاء کے حوالوں کے لیے استعمال ہوتا ہے۔

Lifecycle-aware اجزاء — Android Jetpack (Lifecycle, LiveData, Flow, coroutines) میں نافذ کردہ ایک آرکیٹیکچرل نقطہ نظر۔ onDestroy پر سبسکرپشنز خود بخود منسوخ ہو جاتی ہیں، جو لیک کی مرکزی کلاس کو ختم کر دیتی ہیں۔

kotlin
class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<List<User>>()
    val data: LiveData<List<User>> get() = _data

    fun loadData() {
        viewModelScope.launch {
            val result = repository.fetchData()
            _data.postValue(result)
            // coroutine auto-cancels on onCleared()
        }
    }
}

viewModelScope اور lifecycleScope — Android میں بلٹ ان CoroutineScope جو متعلقہ لائف سائیکل ایونٹ پر منسوخ ہو جاتے ہیں۔ یہ coroutines کے ذریعے لیک کو ختم کرتا ہے — جدید Android ڈویلپمنٹ میں سب سے عام منظرنامہ۔

  • استعمال نہ کریں Context، Activity، View یا Fragment کے جامد حوالہ جات
  • منسوخ کریں onDestroy پر disposeBag / CompositeDisposable میں تمام RxJava سبسکرپشنز
  • استعمال کریں iOS closures میں [weak self] / [unowned self] برقرار رکھنے کے چکروں کو روکنے کے لیے
  • چیک کریں Bitmap اور بڑے آبجیکٹ — انہیں ری سائیکل یا null کیا جانا چاہیے

میموری پروفائلنگ کے اوزار

Android Studio میں Memory Profiler — ہیپ مانیٹرنگ کے لیے بنیادی آلہ۔ یہ لائیو ایلوکیشن، ہیپ سنیپ شاٹس اور قسم کے لحاظ سے آبجیکٹ کی گنتی دکھاتا ہے۔ یہ ڈمپ ریکارڈ کرنے اور مشکوک آبجیکٹ تلاش کرنے کے لیے MAT (Memory Analyzer Tool) میں تجزیہ کرنے کی اجازت دیتا ہے۔

Eclipse MAT — ڈیسک ٹاپ ہیپ ڈمپ تجزیہ کار۔ Android Studio سے HPROF فائل لوڈ کرنے کے بعد، MAT ایک ڈومینیٹر ٹری بناتا ہے، ہر آبجیکٹ کا retain size دکھاتا ہے اور Leak Suspects Report کے ذریعے خودکار مشکوک لیک تجزیہ پیش کرتا ہے۔

Xcode Memory Graph — برقرار رکھنے کے چکروں کا بصری ڈیبگر۔ Memory Graph Debugger بٹن پر کلک کرنے پر، Xcode ایپ کو روکتا ہے، میموری میں ایک مکمل آبجیکٹ گراف بناتا ہے اور برقرار رکھنے کے چکروں کو سرخ رنگ میں نمایاں کرتا ہے۔

آلہپلیٹ فارمخصوصیت
LeakCanaryAndroidتباہی کے بعد خودکار لیک کھوج
Memory ProfilerAndroid Studioہیپ ڈمپ + لائیو ایلوکیشن
Eclipse MATAndroidڈومینیٹر ٹری، Leak Suspects Report
Memory GraphiOS (Xcode)برقرار رکھنے کے چکروں کا بصری آلہ

Google I/O 2023 کے مطابق، ڈیبگ بلڈ میں LeakCanary استعمال کرنے والی ایپس اپنانے کے پہلے 2 مہینوں میں میموری سے متعلق کریشز کو 30–50% کم کرتی ہیں۔ پروجیکٹ آن بورڈنگ مرحلے میں LeakCanary شامل کرنے کی سفارش کی جاتی ہے۔

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

میموری لیک پھولنے سے کیسے مختلف ہے؟

لیک — آبجیکٹ جو کوڈ کے لیے قابل رسائی نہیں لیکن فعال حوالوں کی وجہ سے GC جمع نہیں کرتا۔ پھولنا — ایپ ان آبجیکٹ کو رکھتی ہے جو منطقی طور پر ضروری ہیں لیکن ضرورت سے زیادہ مقدار میں (مثال: 80 MB چلنے والی ایپ میں 50 MB کیش)۔ پھولنا آرکیٹیکچرل طور پر حل ہوتا ہے، لیک — درست حوالہ جات کے انتظام سے۔

LeakCanary لیک کیسے تلاش کرتا ہے؟

LeakCanary ObjectWatcher استعمال کرتا ہے — Activity کے onDestroy() کے بعد، یہ Activity پر ایک WeakReference بناتا ہے اور GC چلاتا ہے۔ اگر 5 سیکنڈ کے بعد WeakReference صاف نہ ہو، تو LeakCanary ہیپ ڈمپ لیتا ہے، GC Root سے آبجیکٹ تک سب سے چھوٹی حوالہ زنجیر کا تجزیہ کرتا ہے اور فائل اور کوڈ لائن کے ساتھ صحیح لیک اسٹیک دکھاتا ہے۔

Bitmap بار بار OutOfMemoryError کیوں کرتا ہے؟

Bitmap جاوا ہیپ سے باہر مقامی میموری (native heap) میں جگہ لیتا ہے۔ ایک Bitmap کا سائز = چوڑائی × اونچائی × 4 بائٹ (ARGB_8888)۔ ایک 12 MP تصویر (4000×3000) 48 MB لیتی ہے۔ Android ہمیشہ بروقت مقامی میموری خالی نہیں کر سکتا، لہٰذا کئی Bitmaps جمع ہونے سے کافی جاوا ہیپ ہونے پر بھی OOM ہوتا ہے۔

iOS میں برقرار رکھنے کا چکر کیا ہے؟

برقرار رکھنے کا چکر — ARC میں ایک صورت حال جہاں دو آبجیکٹ ایک دوسرے کے مضبوط حوالہ جات رکھتے ہیں اور حوالہ شمار کبھی صفر تک نہیں پہنچتا۔ عام مثال: ایک ViewController جس میں closure کا مضبوط حوالہ ہے، اور closure self کو مضبوطی سے پکڑتا ہے۔ حل: closures میں [weak self] یا [unowned self] استعمال کریں۔

Android پر زیادہ سے زیادہ ہیپ سائز کیا ہے؟

ہیپ کا سائز ڈیوائس اور Android ورژن پر منحصر ہے۔ پرانے ڈیوائسز (API 15–24) کے لیے — 64–128 MB۔ جدید (API 25+) کے لیے — 256–512 MB۔ صحیح قیمت ActivityManager.getMemoryClass() کے ذریعے حاصل کی جا سکتی ہے۔ بڑی ایپس (گیمز، ایڈیٹرز) کے لیے، manifest میں largeHeap=true 1 GB تک فراہم کرتا ہے۔

خلاصہ

  • میموری لیک — روٹ سیٹ سے فعال حوالہ کی وجہ سے GC کے ذریعے جمع نہ ہونے والا آبجیکٹ؛ پھولنا — واضح لیک کے بغیر ضرورت سے زیادہ میموری استعمال
  • Activity، Context یا View کے جامد حوالہ جات — Android میں لیک کی پہلی وجہ؛ حل — WeakReference یا Application Context
  • گمنام کلاسز اور لیمبڈا بیرونی کلاس کا واضح حوالہ رکھتے ہیں؛ منسوخ نہ کیے گئے کال بیک دوسری سب سے عام وجہ
  • LeakCanary — Android میں خودکار لیک کھوج کا معیار؛ انضمام میں 5 منٹ لگتے ہیں اور کریش کی شرح 30–50% کم کرتا ہے
  • lifecycleScope اور viewModelScope تباہی پر coroutines کو خود بخود منسوخ کرتے ہیں، لیک کی پوری کلاس ختم کرتے ہیں
  • iOS میں برقرار رکھنے کے چکر closures اور ڈیلیگیٹس میں weak/unowned self سے حل ہوتے ہیں
  • میموری پروفائل کریں — ہر سپرنٹ میں کم از کم ایک بار، MAT یا Memory Graph کے ساتھ ہیپ ڈمپ کوڈ ریویو کا حصہ ہونا چاہیے

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

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

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

مزید پڑھیں