JIT (Just-In-Time) एक गतिशील संकलन तकनीक है जो बाइटकोड या प्रोग्राम के मध्यवर्ती प्रतिनिधित्व को निष्पादन के दौरान सीधे मशीन निर्देशों में बदलती है। Android में, JIT संकलक पहली बार संस्करण 2.2 Froyo में Dalvik वर्चुअल मशीन के भाग के रूप में दिखाई दिया और एप्लिकेशन निष्पादन को 2–5 गुना तेज कर दिया। Google, 2024 के अनुसार, ART में आधुनिक JIT व्याख्या को हॉट मेथड्स की प्रोफाइल्ड संकलन के साथ जोड़ता है।
मुख्य बिंदु
Just-In-Time (JIT) एक संकलन विधि है जिसमें स्रोत कोड या बाइटकोड को पहले से नहीं (जैसे AOT में), बल्कि प्रोग्राम के संबंधित भाग की पहली कॉल के समय मशीन निर्देशों में बदला जाता है। शब्द “Just-In-Time” का अर्थ है कि संकलन “सही समय पर” होता है — निष्पादन से ठीक पहले।
JIT की अवधारणा 1960 के दशक से मौजूद है, लेकिन 1995 में Java वर्चुअल मशीन के आगमन के साथ व्यापक रूप से अपनाई गई। JIT बाइटकोड की पोर्टेबिलिटी (एक बार लिखें — कहीं भी चलाएँ) को नेटिव कोड के करीब प्रदर्शन के साथ जोड़ने की अनुमति देता है। Java HotSpot VM में, JIT संकलक निष्पादित कोड का विश्लेषण करता है और केवल सबसे महत्वपूर्ण भागों को संकलित करता है, समय और मेमोरी बचाता है।
JIT संकलक इनपुट के रूप में बाइटकोड प्राप्त करता है, इसकी व्याख्या करता है, और समानांतर में आँकड़े एकत्र करता है। जब कोड का कोई भाग (मेथड, लूप) पर्याप्त बार कॉल किया जाता है, JIT इसे संकलित करने का निर्णय लेता है। संकलित मशीन कोड कैश में संग्रहीत होता है — बाद की कॉल पर, पहले से संकलित संस्करण का उपयोग होता है। यह पूरे प्रोग्राम को संकलित किए बिना त्वरण प्रदान करता है।
// उदाहरण: एक मेथड कई कॉल के बाद हॉट बन जाती है
public class HotMethod {
private int compute(int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += i * i;
}
return sum;
}
}
// लूप में 500 बार कॉल करना — JIT compute को संकलित करेगा
for (int t = 0; t < 500; t++) {
hot.compute(1000);
}
Android में, JIT संकलन विकास के तीन चरणों से गुज़रा। पहला चरण — Dalvik बिना JIT (Android 1.0–2.1): DEX बाइटकोड की शुद्ध व्याख्या। दूसरा चरण — Dalvik JIT के साथ (Android 2.2–4.4): JIT संकलक की शुरुआत, जिसने एप्लिकेशन को 2–5 गुना तेज किया। तीसरा चरण — ART हाइब्रिड JIT के साथ (Android 7.0+): एक नई क्षमता में JIT की वापसी।
Dalvik में JIT को ट्रेस-आधारित संकलक के रूप में लागू किया गया था। यह व्यक्तिगत मेथड्स का नहीं, बल्कि निर्देशों की श्रृंखलाओं (ट्रेसेस) का विश्लेषण करता था जो क्रमिक रूप से बार-बार निष्पादित होते हैं। यह कई मेथड्स सहित संपूर्ण निष्पादन पथों को संकलित करने की अनुमति देता था। यह दृष्टिकोण छोटे निर्देश कैश वाले मोबाइल प्रोसेसर के लिए प्रभावी था, क्योंकि संकलित ट्रेस L1 कैश में समा जाता था।
Android 7.0 Nougat से शुरू होकर, ART मेथड-आधारित JIT का उपयोग करता है — यह निष्पादन प्रोफाइल के आधार पर व्यक्तिगत मेथड्स को संकलित करता है। यह JIT Dalvik JIT से काफी तेज काम करता है: एक मेथड के लिए विशिष्ट संकलन समय 0.5–1 मिलीसेकंड है, जबकि Dalvik में 3–5 मिलीसेकंड। संकलित कोड एप्लिकेशन हीप के बजाय एक अलग मेमोरी क्षेत्र (JIT कोड कैश) में संग्रहीत होता है, जो विखंडन को कम करता है।
| पैरामीटर | Dalvik JIT | ART JIT |
|---|---|---|
| प्रकार | ट्रेस-आधारित | मेथड-आधारित |
| संकलन गति | 3–5 मिलीसेकंड/मेथड | 0.5–1 मिलीसेकंड/मेथड |
| संकलन सीमा | ~200 कॉल | गतिशील |
| कोड कैश | एप्लिकेशन हीप में | JIT कोड कैश |
| प्रोफाइलिंग | आंतरिक | बाहरी .prof फ़ाइलें |
JIT का केंद्रीय तंत्र हॉट मेथड डिटेक्शन है। प्रत्येक मेथड कॉल एक आंतरिक काउंटर बढ़ाती है। जब काउंटर सीमा पार करता है, मेथड को “हॉट” चिह्नित किया जाता है और संकलन के लिए भेजा जाता है। Dalvik में, सीमा निश्चित थी (~200 कॉल)। ART में, काउंटर डिवाइस के उपलब्ध संसाधनों के आधार पर गतिशील रूप से कॉन्फ़िगर होते हैं।
संकलन प्रक्रिया में कई चरण शामिल हैं। पहला — बाइटकोड विश्लेषण: JIT निर्देश प्रवाह की जाँच करता है और डेटा-फ़्लो ग्राफ़ बनाता है। दूसरा — ऑप्टिमाइज़ेशन: छोटी मेथड्स का इनलाइनिंग, मृत कोड हटाना, कॉन्स्टेंट फोल्डिंग। तीसरा — कोड जनरेशन: विशिष्ट CPU आर्किटेक्चर (ARM, ARM64, x86) के लिए ऑप्टिमाइज़्ड ग्राफ़ को मशीन निर्देशों में बदलना।
// इनलाइनिंग का प्रदर्शन — JIT मेथड बॉडी को इनलाइन करेगा
public int inlineExample() {
return square(5);
}
private int square(int x) {
return x * x;
} // JIT कॉल को return 5 * 5; से बदल देगा
JIT की एक विशेष तकनीक — ऑन-स्टैक रिप्लेसमेंट (OSR). यदि किसी मेथड में एक लंबा लूप है जो सैकड़ों पुनरावृत्तियों के लिए समाप्त नहीं होता, JIT लूप को “चलते-फिरते” संकलित कर सकता है और व्याख्यित संस्करण को निष्पादन के दौरान ही संकलित संस्करण से बदल सकता है। OSR विशेष रूप से कम्प्यूटेशनल कार्यों के लिए प्रभावी है: रेंडरिंग, इमेज प्रोसेसिंग, क्रिप्टोग्राफी।
JIT और AOT विपरीत समझौतों वाले दो संकलन दृष्टिकोण हैं। JIT कॉम्पैक्ट वितरण आकार और अनुकूलनशीलता के लिए पहले लॉन्च की गति का त्याग करता है। AOT अधिकतम प्रदर्शन के लिए इंस्टॉलेशन समय और डिस्क स्थान का त्याग करता है। कोई भी दृष्टिकोण पूरी तरह बेहतर नहीं है — चुनाव परिदृश्य पर निर्भर करता है।
JIT का मुख्य लाभ है अनुकूली ऑप्टिमाइज़ेशन। JIT AOT के लिए उपलब्ध नहीं होने वाली प्रोफ़ाइल जानकारी का उपयोग कर सकता है: सटीक ऑब्जेक्ट प्रकार, वास्तविक कॉल आवृत्ति, वास्तविक ब्रांचिंग पैटर्न। यह स्थैतिक संकलन के साथ असंभव आक्रामक ऑप्टिमाइज़ेशन लागू करने की अनुमति देता है। उदाहरण के लिए, JIT मेथड कॉल को डिवर्चुअलाइज़ कर सकता है यदि व्यवहार में केवल एक रिसीवर प्रकार पाया जाता है।
| मानदंड | JIT | AOT |
|---|---|---|
| इंस्टॉलेशन समय | तत्काल | आकार पर निर्भर |
| पहला लॉन्च | धीमा (वार्म-अप) | तेज़ |
| डिस्क स्थान | न्यूनतम | +15–30% |
| अनुकूलनशीलता | उच्च | निम्न |
| CPU उपयोग | संकलन के दौरान चोटियाँ | स्थिर |
JIT संकलन तब बेहतर होता है जब तेज़ परिनियोजन और डिस्क स्थान की बचत महत्वपूर्ण हो। मोबाइल डेवलपमेंट के संदर्भ में, JIT उन एप्लिकेशन के लिए आदर्श है जो बार-बार अपडेट होते हैं (A/B परीक्षण, हॉटफ़िक्स)। JIT डेवलपमेंट के दौरान भी सुविधाजनक है, जब कोड दिन में दर्जनों बार पुनर्निर्मित होता है — संकलन पर बचाया गया प्रत्येक सेकंड फीडबैक लूप को तेज करता है।
JIT डेवलपर्स को कई व्यावहारिक लाभ प्रदान करता है। पहला — छोटा APK आकार। JIT दृष्टिकोण के साथ, APK में केवल बाइटकोड (DEX) पैक होता है, जो संकलित नेटिव कोड से 20–30% कम स्थान लेता है। सीमित आंतरिक स्टोरेज वाले उपयोगकर्ताओं के लिए, यह एक महत्वपूर्ण लाभ है।
दूसरा लाभ है डिवाइस अनुकूलन। JIT वास्तविक CPU आर्किटेक्चर, RAM आकार और वर्तमान लोड को ध्यान में रखते हुए कोड संकलित करता है। उदाहरण के लिए, 2 GB RAM वाले डिवाइस पर, JIT मेमोरी बचाने के लिए कम आक्रामक रूप से संकलित कर सकता है, जबकि 12 GB वाले फ्लैगशिप पर सभी संभव ऑप्टिमाइज़ेशन लागू कर सकता है। AOT संकलन, दूसरी ओर, इंस्टॉलेशन के समय निर्णय को स्थिर कर देता है।
बाइटकोड प्लेटफ़ॉर्म-स्वतंत्र रहता है, जो एप्लिकेशन वितरण को सरल बनाता है। एक APK ARM, ARM64 और x86 डिवाइस पर काम करता है, और JIT प्रत्येक आर्किटेक्चर के लिए नेटिव कोड उत्पन्न करता है। AOT दृष्टिकोण के लिए APK में कई नेटिव कोड वेरिएंट शामिल करने (आकार बढ़ाने) या प्रत्येक आर्किटेक्चर के लिए अलग संस्करण संकलित करने की आवश्यकता होगी।
JIT का मुख्य नुकसान है वार्म-अप देरी। उपयोगकर्ता को एप्लिकेशन के पहले सेकंड में धीमापन महसूस होता है जबकि JIT हॉट मेथड्स को संकलित करता है। गेम में, यह प्रारंभिक स्तरों में हकलाने के रूप में प्रकट होता है। एनिमेशन वाले एप्लिकेशन में — स्क्रीन के बीच पहले ट्रांज़िशन में झटके।
दूसरा नुकसान — बिजली की खपत। संकलन प्रक्रिया CPU को भारी लोड करती है, वार्म-अप अवधि के दौरान बिजली की खपत 10–20% बढ़ा देती है। बैटरी पर चलने वाले उपकरणों पर, यह बैटरी जीवन को कम करता है। यह विशेष रूप से बार-बार एप्लिकेशन पुनरारंभ वाले परिदृश्यों में ध्यान देने योग्य है (सीमित मेमोरी के साथ मल्टीटास्किंग, जहाँ सिस्टम प्रक्रियाओं को अनलोड और रीलोड करता है)।
एक और समस्या — JIT कैश विखंडन। संकलित कोड एक सतत मेमोरी क्षेत्र में संग्रहीत होता है। जब नई क्लासेज़ लोड होती हैं और अतिरिक्त मेथड्स संकलित होते हैं, कैश विखंडित हो जाता है, जिससे मेमोरी प्रबंधन ओवरहेड बढ़ जाता है। Dalvik में, यह समस्या आवधिक कैश सफाई द्वारा हल की गई थी; ART में, JIT कैश हीप से अलग आवंटित होता है और अपनी स्वयं की डीफ़्रैग्मेंटेशन रणनीति का उपयोग करता है।
ART में आधुनिक दृष्टिकोण — हाइब्रिड संकलन, JIT और AOT की ताकतों को जोड़ता है। एप्लिकेशन इंस्टॉलेशन के दौरान, कोई संकलन नहीं किया जाता — केवल बाइटकोड सत्यापन (verify)। यह तेज़ इंस्टॉलेशन और न्यूनतम स्थान उपयोग सुनिश्चित करता है। पहले लॉन्च हॉट मेथड्स के JIT संकलन के साथ व्याख्या मोड में चलते हैं — उपयोगकर्ता को लंबे इंतज़ार के बिना स्वीकार्य प्रदर्शन मिलता है।
समानांतर में, एक पृष्ठभूमि प्रोफ़ाइलर वास्तविक उपयोग के बारे में डेटा एकत्र करता है। 2–3 पूर्ण एप्लिकेशन लॉन्च के बाद, प्रोफ़ाइल पर्याप्त पूर्णता तक पहुँचती है, और सिस्टम हॉट मेथड्स को नेटिव कोड में संकलित करने के लिए dex2oat चलाता है। यह ऑपरेशन पृष्ठभूमि में तब किया जाता है जब डिवाइस लोडेड न हो (चार्जिंग, स्क्रीन बंद)। पृष्ठभूमि AOT पूरा होने के बाद, एप्लिकेशन पूर्ण AOT संकलन के बराबर प्रदर्शन प्राप्त करता है।
# पृष्ठभूमि संकलन का बलपूर्वक प्रारंभ
adb shell cmd package compile -m speed-profile -f com.example.app
# संकलन स्थिति देखें
adb shell cmd package dump-profiles com.example.app
Google I/O 2017 के अनुसार, हाइब्रिड संकलन ने शुद्ध AOT की तुलना में एप्लिकेशन इंस्टॉलेशन समय को 30–50% कम कर दिया। सिस्टम विभाजन पर कब्जा किया गया डिस्क स्थान 20–30% कम हो गया। साथ ही, पृष्ठभूमि संकलन के बाद प्रदर्शन पूर्ण AOT के स्तर से मेल खाता है। एकमात्र परिदृश्य जहाँ हाइब्रिड AOT से कमतर है, वह है इंस्टॉलेशन के तुरंत बाद पहला लॉन्च: एप्लिकेशन JIT मोड में चलता है और 10–15% धीमा हो सकता है।
अक्सर पूछे जाने वाले प्रश्न
JIT एक प्रोग्राम को तेज़ करने का तरीका है जहाँ कोड का मशीन भाषा में अनुवाद पहले से नहीं, बल्कि चलने के दौरान भागों में किया जाता है। सबसे लगातार भाग संकलित और कैश किए जाते हैं, जबकि दुर्लभ भाग अपने मूल रूप में रहते हैं।
JIT निष्पादन के दौरान कोड संकलित करता है, स्थान बचाता है और इंस्टॉलेशन को तेज़ करता है। AOT पहले से सारा कोड संकलित करता है — एप्लिकेशन तेज़ी से शुरू होता है लेकिन अधिक डिस्क स्थान और इंस्टॉलेशन समय की आवश्यकता होती है।
JIT हटाया नहीं गया — यह विकसित हुआ। Android 5.0 में, JIT के साथ Dalvik को शुद्ध AOT के साथ ART से बदल दिया गया। Android 7.0 में, JIT एक हाइब्रिड सिस्टम के हिस्से के रूप में ART में वापस आया जहाँ यह इष्टतम प्रदर्शन के लिए पृष्ठभूमि AOT संकलन के साथ मिलकर काम करता है।
JIT CPU लोड के कारण वार्म-अप अवधि के दौरान बिजली की खपत 10–20% बढ़ा देता है। हॉट मेथड संकलन पूरा होने के बाद, बिजली की खपत सामान्य स्तर पर लौट आती है। ART का हाइब्रिड मोड पृष्ठभूमि संकलन के माध्यम से इन चोटियों को कम करता है।
हाँ, गहन गणना वाले परिदृश्यों में। उपयोगकर्ता एप्लिकेशन के पहले सेकंड में या गेम की शुरुआत में धीमापन देख सकता है। Android (8.0+) के आधुनिक संस्करणों में, हाइब्रिड मोड प्रोफाइल्ड संकलन के कारण इस प्रभाव को कम करता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें