گاربیج کلیکشن کے ذریعے خودکار میموری مینجمنٹ Android پلیٹ فارم کا ایک کلیدی طریقہ کار ہے، جو ART ورچوئل مشین پر مبنی ہے۔ Google Android Documentation، 2026 کے مطابق، گاربیج کلیکٹر ڈویلپر کو دستی میموری مینجمنٹ سے آزاد کرتا ہے، خود بخود ان اشیاء کو ہٹا کر جن کا کوئی حوالہ نہیں رہا۔ GC کے بغیر، ہر آبجیکٹ مختص کرنے کے لیے واضح طور پر free یا delete کال کی ضرورت ہوگی، جو Java ماحولیاتی نظام میں لاکھوں اشیاء فی سیکنڈ کے ساتھ جسمانی طور پر ناممکن ہے۔
اہم نکات
Garbage Collection (GC) ان اشیاء کے زیر قبضہ میموری کو خودکار طور پر دریافت کرنے اور خالی کرنے کا عمل ہے جو پروگرام کے ذریعے مزید استعمال نہیں ہوتیں۔ موبائل ڈویلپمنٹ کے تناظر میں، GC Android پلیٹ فارم پر ART ورچوئل مشین کے ذریعے، نیز معیاری Java Virtual Machine میں استعمال ہوتا ہے۔
دستی میموری مینجمنٹ والی زبانوں (C، C++) کے برعکس، جہاں پروگرامر کو واضح طور پر free یا delete کال کرنا ہوتی ہے، GC اشیاء کی زندگی کے چکر کو ٹریک کرنے کا کام مکمل طور پر سنبھال لیتا ہے۔ ڈویلپر new آپریٹر کے ذریعے نئی اشیاء بناتا ہے، جبکہ کلیکٹر یہ طے کرتا ہے کہ کوئی آبجیکٹ کب ناقابل رسائی ہو جاتا ہے — یعنی اس کا کوئی فعال حوالہ نہیں رہتا۔
GC کارکردگی کے اہم میٹرکس توقف کا وقت (pause time) اور تھرو پٹ (throughput) ہیں۔ توقف وہ مدت ہے جس کے دوران کلیکشن کے لیے ایپلیکیشن کا عمل روک دیا جاتا ہے۔ موبائل ماحول میں، 8–16 ملی سیکنڈ سے زیادہ طویل توقف گرے ہوئے فریم (jank) کے طور پر محسوس ہوتے ہیں۔
Google I/O 2019 کے مطابق، Android 10 میں ART نے عام GC توقف کو 2–4 ms تک کم کر دیا، جو Android 4.4 میں Dalvik کے مقابلے میں 70% کم ہے۔ اس کے باوجود، نامناسب میموری مینجمنٹ — لوپ میں بار بار آبجیکٹ مختص کرنا، غیر ضروری عارضی مثالیں بنانا — کارکردگی کے مسائل کی بنیادی وجہ بنی ہوئی ہے۔
Java اور Android میں GC کے تمام نفاذ کئی بنیادی الگورتھم پر مبنی ہیں جو توقف کے وقت اور صفائی کی مکملیت کے درمیان توازن حاصل کرنے کے لیے مل جاتے ہیں۔ ان الگورتھم کو سمجھنا GC دوست کوڈ لکھنے کے لیے ضروری ہے۔
Mark-and-Sweep سب سے آسان الگورتھم ہے، جو دو مراحل میں کام کرتا ہے۔ Mark مرحلے میں، کلیکٹر جڑ کے حوالوں (root set) — مقامی متغیرات، جامد فیلڈز، تھریڈ اسٹیک — سے شروع کرکے آبجیکٹ گراف کو traverse کرتا ہے۔ ہر قابل رسائی آبجیکٹ کو زندہ جھنڈی سے نشان زد کیا جاتا ہے۔ Sweep مرحلے میں، کلیکٹر پورے ہیپ کو اسکین کرتا ہے اور غیر نشان زدہ اشیاء کی میموری خالی کرتا ہے۔
نقصان میموری کی بکھراؤ ہے: Sweep کے بعد، خالی علاقے بھرے ہوئے علاقوں کے ساتھ متبادل ہوتے ہیں، جس سے بڑی اشیاء کا مختص کرنا مشکل ہو جاتا ہے۔ موبائل منظرناموں میں، یہ اہم ہے کیونکہ ہیپ عام طور پر چھوٹا ہوتا ہے (Android پر 64–512 MB)۔
Copying Collection ہیپ کو دو نصف جگہوں (semi-spaces) میں تقسیم کرتا ہے۔ فعال اشیاء کو بغیر خلا کے ایک نصف جگہ سے دوسری میں کمپیکٹ طور پر کاپی کیا جاتا ہے۔ کاپی کرنے کے بعد، پرانی نصف جگہ مکمل طور پر خالی قرار دے دی جاتی ہے۔ الگورتھم بکھراؤ کو مکمل طور پر ختم کرتا ہے، لیکن دو گنا میموری کی ضرورت ہوتی ہے۔
موبائل ماحول میں، Copying Collection کا استعمال نسلی کلیکٹرز جوان اشیاء کی تیز صفائی کے لیے کرتے ہیں، جو اعداد و شمار کے مطابق جلد مر جاتی ہیں (کمزور نسلی مفروضہ)۔
Generational Collection ہیپ کو نسلوں میں تقسیم کرتا ہے: Young Generation (جوان اشیاء) اور Old Generation (پرانی اشیاء جو کئی کلیکشن سے بچ گئیں)۔ جوان نسل کا کلیکشن (Minor GC) بار بار اور تیزی سے کیا جاتا ہے، کیونکہ زیادہ تر اشیاء جوان مر جاتی ہیں۔ پرانی نسل کا کلیکشن (Major GC یا Full GC) کم بار ہوتا ہے لیکن زیادہ دیر تک چلتا ہے۔
// نسلی GC کا مظاہرہ: جوان اشیاء جلد مر جاتی ہیں
void processItems(List<Item> items) {
List<Result> results = new ArrayList<>(); // پورے طریقہ کار تک زندہ رہتا ہے
for (Item item : items) {
Result r = new Result(item.getValue()); // فوری طور پر مر جاتا ہے
if (r.isValid()) {
process(r); // r کوڑا بن جاتا ہے
}
}
saveResults(results); // results Old Gen میں منتقل ہو جاتا ہے
}
اس مثال میں، Result اشیاء لوپ کے اندر بنائی جاتی ہیں اور فوراً کوڑا بن جاتی ہیں — یہ Young GC کے لیے مثالی امیدوار ہیں۔ results آبجیکٹ زیادہ دیر زندہ رہتا ہے اور Old Generation میں منتقل ہو جاتا ہے۔ نسلوں کی علیحدگی Minor GC کو پرانے ہیپ کو چھوئے بغیر ملی سیکنڈز میں جوان اشیاء صاف کرنے کی اجازت دیتی ہے۔
Android Dalvik VM سے ART (Android Runtime) تک ترقی کر گیا، اور GC کا نفاذ ان کے درمیان اہم فرقوں میں سے ایک ہے۔ Android میں GC فن تعمیر کو سمجھنا حقیقی آلات پر توقف کم سے کم کرنے والا کوڈ لکھنے میں مدد کرتا ہے۔
| خصوصیت | Dalvik (4.4 تک) | ART (5.0+) |
|---|---|---|
| GC قسم | Concurrent Mark کے ساتھ Mark-and-Sweep | Generational + Concurrent |
| عام توقف | 10–30 ms | 2–4 ms |
| سکڑاؤ (Compaction) | نہیں (صرف بکھراؤ بڑھتا ہے) | ہاں (پس منظر میں، ایپ کو روکے بغیر) |
| AOT تالیف | JIT (Just-In-Time) | AOT + JIT (ہائبرڈ) |
Dalvik نے Mark-and-Sweep کا ایک ہم وقت مرحلے کے ساتھ مجموعہ استعمال کیا۔ Concurrent Mark نے آبجیکٹ گراف کے traverse کے دوران ایپلیکیشن کو کام جاری رکھنے کی اجازت دی، لیکن Sweep مرحلے کے لیے تمام تھریڈز کو روکنا ضروری تھا (Stop-The-World)۔ کم RAM والے آلات (512 MB — 1 GB) پر، توقف 30 ms تک پہنچ گیا، جس سے انٹرفیس میں قابل توجہ سستی پیدا ہوئی۔ مزید برآں، Dalvik نے ہیپ کو سکڑایا نہیں، لہٰذا طویل استعمال کے بعد بکھراؤ بڑھ گیا اور بڑی اشیاء (مثلاً Bitmap) کا مختص کرنا کافی کل خالی میموری ہونے کے باوجود OutOfMemoryError پھینک سکتا تھا۔
ART (Android Runtime) نے ہم وقت سکڑاؤ کے ساتھ ایک نسلی کلیکٹر متعارف کرایا۔ ہیپ تین خطوں میں تقسیم ہے: Young، Mature (Old Generation کے مشابہ) اور Large Object Space (12 KB سے بڑی اشیاء کے لیے)۔ زیادہ تر معاملات میں Young Region کا کلیکشن تھریڈز کو روکے بغیر متوازی طور پر ہوتا ہے۔ Android 10+ میں، Concurrent Copying متعارف کرائی گئی — سکڑاؤ Stop-The-World کے بغیر پس منظر کے تھریڈ میں چلتا ہے۔
ART کے فن تعمیر کی بدولت، عام GC توقف 2–4 ms تک کم ہو گیا، اور جوان اشیاء کے غلبہ والے منظرناموں میں — 0.5–1 ms تک۔ اس نے Android آلات کو فعال میموری کارروائیوں کے دوران بھی مستحکم 60 FPS برقرار رکھنے کی اجازت دی۔
Java ماحولیاتی نظام میں، GC کے کئی نفاذ ہیں، ہر ایک کا اپنا کارکردگی پروفائل ہے۔ Android ڈویلپمنٹ کے لیے، انتخاب ART تک محدود ہے، لیکن Java GC کا علم موبائل ایپلیکیشنز کے لیے سرور سائیڈ کوڈ لکھتے وقت اور Kotlin Multiplatform کے ساتھ ڈویلپمنٹ کے وقت مفید ہے۔
Serial GC مکمل ایپلیکیشن سٹاپ (Stop-The-World) کے ساتھ ایک واحد تھریڈ والا کلیکٹر ہے۔ ہر Mark، Sweep اور Compact آپریشن ایک تھریڈ کے ذریعے کیا جاتا ہے۔ کارکردگی کم ہے — موبائل سرورز کے لیے استعمال نہیں ہوتا۔ صرف 100 MB تک ہیپ والی چھوٹی ایپلیکیشنز کے لیے موزوں ہے۔
Parallel GC (تھرو پٹ کلیکٹر کے نام سے بھی جانا جاتا ہے) تمام کلیکشن مراحل کے لیے متعدد تھریڈز استعمال کرتا ہے۔ یہ زیادہ سے زیادہ تھرو پٹ (throughput) کی طرف مبنی ہے — ایپلیکیشن رن ٹائم کے مقابلے GC پر صرف ہونے والے وقت کو کم سے کم کرنا۔ JVM میں -XX:+UseParallelGC فلیگ کے ذریعے فعال کیا جاتا ہے۔
G1 (Garbage-First) GC Java 9+ میں ڈیفالٹ کلیکٹر ہے۔ ہیپ 1–32 MB کے خطوں میں تقسیم ہے۔ G1 توقف کے وقت کی پیش گوئی کرتا ہے اور متعین حد (ڈیفالٹ 200 ms) کے اندر رہنے کی کوشش کرتا ہے۔ ترجیح: سب سے زیادہ کوڑے والے خطے پہلے صاف کیے جاتے ہیں (اسی لیے نام)۔ G1 پیش گوئی کے قابل توقف کے ساتھ بڑے ہیپ والے سرورز (4–64 GB) کے لیے موثر ہے۔
// 100 ms ہدف توقف کے ساتھ G1 GC کو فعال کرنا
// java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -jar app.jar
public class MemoryMonitor {
private static final long THRESHOLD = 512 * 1024 * 1024; // 512 MB
public void checkHeapUsage() {
Runtime rt = Runtime.getRuntime();
long used = rt.totalMemory() - rt.freeMemory();
if (used > THRESHOLD) {
System.out.println("Heap usage exceeded threshold: " + used);
System.out.println("Consider reducing allocations");
}
}
}
Runtime کے ذریعے ہیپ کی نگرانی ابتدائی مرحلے میں میموری لیک کا پتہ لگانے کی اجازت دیتی ہے۔ اگر مستحکم آپریشن میں used زیادہ سے زیادہ ہیپ کے 80% سے تجاوز کر جائے — یہ ممکنہ لیک یا ایپلیکیشن کے ضرورت سے زیادہ میموری استعمال کا اشارہ ہے۔
جدید ART GC بھی تمام مسائل حل نہیں کرتا — نامناسب میموری کا استعمال jank اور ANR (Application Not Responding) کی بنیادی وجہ بنا ہوا ہے۔ آئیے اہم منظرناموں اور بہتری کے طریقوں کو دیکھتے ہیں۔
GC توقف — کلیکشن کے دوران ایپلیکیشن تھریڈز کا رک جانا۔ اسکرین پر، یہ گرے ہوئے فریم کے طور پر ظاہر ہوتا ہے، جب دو فریموں کے درمیان وقت 16.6 ms (60 FPS) سے تجاوز کر جائے۔ اگر GC 30 ms تک رہے تو دو کے بجائے صرف ایک فریم کھینچا جاتا ہے — صارف انٹرفیس میں ہچکی دیکھتا ہے۔
طویل توقف کی بنیادی وجوہات: Old Generation میں بڑی تعداد میں زندہ اشیاء، ہیپ کا بکھراؤ، بار بار Full GC۔ تشخیص کے لیے Android Studio Profiler اور systrace استعمال ہوتے ہیں۔
GC دوست کوڈ کا بنیادی اصول مختص کردہ اشیاء کی تعداد کو کم سے کم کرنا ہے۔ ہر نئی آبجیکٹ کو نہ صرف میموری مختص کرنے کی ضرورت ہوتی ہے بلکہ بعد میں کلیکشن کی بھی۔ چاہے GC تیز ہو، فی سیکنڈ 1000 اضافی مختصات کلیکٹر کے لیے 1000 جانچیں پیدا کرتے ہیں۔
میموری لیک اس وقت ہوتا ہے جب کوئی آبجیکٹ قابل رسائی رہتا ہے حالانکہ اس کی مزید ضرورت نہیں۔ GC ایسی آبجیکٹ کو حذف نہیں کر سکتا اور میموری آہستہ آہستہ ختم ہو جاتی ہے۔ عام وجوہات: غیر رجسٹرڈ سننے والے، Activity کے جامد حوالے، بیرونی سیاق و سباق کو پکڑنے والی گمنام کلاسیں اور بند نہ کیے گئے Cursor/InputStream۔
// میموری لیک: گمنام کلاس Activity کا حوالہ رکھتی ہے
public void startTask() {
new Thread(new Runnable() { // مضمر طور پر this (Activity) رکھتا ہے
@Override
public void run() {
// طویل کارروائی...
System.out.println("Done");
}
}).start();
}
// اصلاح: جامد اندرونی کلاس + WeakReference
private static class TaskRunnable implements Runnable {
private WeakReference<Activity> activityRef;
TaskRunnable(Activity activity) {
this.activityRef = new WeakReference<>(activity);
}
@Override
public void run() {
Activity act = activityRef.get();
if (act != null) {
// Activity کے ساتھ محفوظ کام
}
}
}
اس مثال میں، گمنام Runnable Activity کا ایک مضمر حوالہ پکڑتا ہے۔ جب تک تھریڈ زندہ ہے — Activity کو GC جمع نہیں کر سکتا، چاہے صارف اسکرین بند کر چکا ہو۔ WeakReference + جامد کلاس کے ساتھ اصلاح اس زنجیر کو توڑتی ہے اور Activity کو آزاد کرنے کی اجازت دیتی ہے۔
اکثر پوچھے گئے سوالات
Android (ART) میں GC ہم وقت سکڑاؤ کے ساتھ ایک نسلی کلیکٹر ہے، جو محدود میموری والے موبائل آلات کے لیے بہتر بنایا گیا ہے۔ Java GC (G1, ZGC) بڑے ہیپ اور پیش گوئی کے قابل توقف والے سرور سائڈ کلیکٹر ہیں۔ ART GC JVM فلیگ استعمال نہیں کرتا — تمام ترتیب OS سطح پر خودکار طور پر ہوتی ہے۔
Stop-The-World وہ لمحہ ہے جب کلیکٹر آبجیکٹ گراف کو محفوظ طریقے سے traverse کرنے یا میموری خالی کرنے کے لیے ایپلیکیشن کے تمام تھریڈز کو روکتا ہے۔ STW جتنا طویل، jank اتنا ہی زیادہ نمایاں۔ ART نے اپنے نسلی فن تعمیر کی بدولت عام STW وقت کو 2–4 ms تک کم کر دیا۔
Android Studio Memory Profiler استعمال کریں — یہ ہیپ کی نمو، مختصات کی تعداد دکھاتا ہے اور Heap Dump لینے کی اجازت دیتا ہے۔ گہرائی سے تجزیہ کے لیے، LeakCanary استعمال کریں — لائبریری خود بخود لیک کا پتہ لگاتی ہے اور GC کلیکشن کو روکنے والی حوالہ زنجیر دکھاتی ہے۔
Full GC Old Generation سمیت تمام ہیپ نسلوں کا مکمل کلیکشن ہے۔ موبائل ایپلیکیشنز میں، Full GC 50–200 ms تک چل سکتا ہے، جس سے نمایاں jank یا ANR پیدا ہو سکتا ہے۔ بنیادی وجوہات: ہیپ کا بکھراؤ، میموری لیک، Old Generation کی حد سے تجاوز۔
Kotlin ساختی ہم وقتی کے ساتھ coroutine فراہم کرتا ہے — دائرہ کار کی منسوخی خود بخود تمام ذیلی coroutine کو منسوخ کر دیتی ہے، لیک کو روکتی ہے۔ Kotlin میں تاخیر سے ابتدا کے لیے lazy ڈیلیگیٹ اور دائرہ کار کے فنکشن بھی ہیں جو عارضی اشیاء کی تعداد کم کرتے ہیں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں