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 কম্পাইলেশন বিবর্তনের তিনটি ধাপ অতিক্রম করেছে। প্রথম ধাপ — JIT ছাড়া Dalvik (Android 1.0–2.1): DEX বাইটকোডের বিশুদ্ধ ব্যাখ্যা। দ্বিতীয় ধাপ — JIT সহ Dalvik (Android 2.2–4.4): JIT কম্পাইলারের প্রবর্তন, যা অ্যাপ্লিকেশনকে 2–5 গুণ ত্বরান্বিত করেছিল। তৃতীয় ধাপ — হাইব্রিড JIT সহ ART (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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন