Dalvik ভার্চুয়াল মেশিনটি Android অপারেটিং সিস্টেমের একটি মূল উপাদান ছিল, যা সংস্করণ 4.4 KitKat পর্যন্ত অ্যাপ্লিকেশন চালানোর জন্য দায়ী ছিল। ড্যান বর্নস্টেইন দ্বারা বিকশিত, এই রেজিস্টার-ভিত্তিক VM স্ট্যান্ডার্ড JVM ধারণাটি প্রতিস্থাপন করেছিল এবং সীমিত RAM সহ মোবাইল ডিভাইসগুলিতে অ্যাপ্লিকেশন লঞ্চ অপ্টিমাইজ করা সম্ভব করেছিল। Google, 2024-এর মতে, Dalvik JIT কম্পাইলেশনের মাধ্যমে অ্যাপ্লিকেশন সামঞ্জস্য নিশ্চিত করেছিল, এক্সিকিউশনের সময় সরাসরি DEX বাইটকোডকে মেশিন নির্দেশে রূপান্তরিত করে।
মূল পয়েন্ট
Dalvik একটি রেজিস্টার-ভিত্তিক আর্কিটেকচার সহ ভার্চুয়াল মেশিন, যা বিশেষভাবে Android প্ল্যাটফর্মের জন্য তৈরি। উন্নয়ন 2005 সালে ড্যান বর্নস্টেইনের কোম্পানি দ্বারা শুরু হয়েছিল এবং 2007 সালে প্রকল্পটি Google অধিগ্রহণ করে। Dalvik-এর প্রথম বাণিজ্যিক সংস্করণ 2008 সালে Android 1.0 রিলিজের সাথে আসে।
স্ট্যান্ডার্ড জাভা ভার্চুয়াল মেশিন (JVM)-এর বিপরীতে, Dalvik জাভা বাইটকোড নির্বাহ করে না। জাভা কম্পাইলার সোর্স কোডকে class ফাইলে রূপান্তর করে, এবং তারপর dx ইউটিলিটি সেগুলিকে Dalvik Executable (DEX) ফরম্যাটে অনুবাদ করে। এই ফরম্যাটটি class ফাইলের চেয়ে বেশি সংক্ষিপ্ত: class ফরম্যাটে 10 MB অ্যাপ্লিকেশন DEX-এ প্রায় 6–7 MB নেয়।
ড্যান বর্নস্টেইন সীমিত সম্পদ সহ অপারেটিং সিস্টেমের জন্য একটি প্রকল্প হিসাবে Dalvik লিখেছিলেন। নামটি আইসল্যান্ডীয় গ্রাম ডালভিক থেকে নেওয়া হয়েছে। Google লাইসেন্সিং বিধিনিষেধ এবং ARM আর্কিটেকচার সহ মোবাইল প্রসেসরের জন্য গভীর অপ্টিমাইজেশনের প্রয়োজনীয়তার কারণে JVM-এর পরিবর্তে Dalvik বেছে নিয়েছিল। সিস্টেমটি দ্রুত জনপ্রিয়তা অর্জন করে: 2012 সালের মধ্যে, 500 মিলিয়নেরও বেশি Android ডিভাইস Dalvik-এ চলছিল।
প্রতিটি Android অ্যাপ্লিকেশন তার নিজস্ব Dalvik VM ইনস্ট্যান্স সহ একটি পৃথক প্রক্রিয়ায় চলে। এটি অপারেটিং সিস্টেম স্তরে ডেটা বিচ্ছিন্নতা এবং দূষিত কোড থেকে সুরক্ষা নিশ্চিত করে। এই পদ্ধতিটি ভার্চুয়ালাইজেশনের সুবিধাগুলিকে Linux স্যান্ডবক্সের সাথে একত্রিত করে — একটি অ্যাপ্লিকেশনের ম্যালওয়্যার পার্শ্ববর্তী প্রক্রিয়াগুলিকে প্রভাবিত করতে পারে না।
Dalvik-এর রেজিস্টার-ভিত্তিক আর্কিটেকচার JVM-এর স্ট্যাক-ভিত্তিক আর্কিটেকচার থেকে মৌলিকভাবে আলাদা। স্ট্যাকের শীর্ষে অপারেশনের পরিবর্তে, Dalvik রেজিস্টার — VM-এর ভিতরে ভার্চুয়াল কোষ — দিয়ে কাজ করে। প্রতিটি নির্দেশে অপারেন্ড রেজিস্টারের ঠিকানা থাকে, যা প্রতি অপারেশনে নির্দেশের সংখ্যা হ্রাস করে।
JVM স্ট্যাক মেশিন push, pop এবং add-এর মতো নির্দেশ ব্যবহার করে — দুটি সংখ্যা যোগ করতে তিনটি নির্দেশ প্রয়োজন। Dalvik তিনটি রেজিস্টার সহ একটি add-int নির্দেশ দিয়ে একই কাজ সমাধান করে। Android Open Source Project-এর মতে, রেজিস্টার-ভিত্তিক DEX আর্কিটেকচার স্ট্যাক-ভিত্তিক class ফরম্যাটের তুলনায় বাইটকোড আকার গড়ে 30% কমায়।
DEX ফাইল (Dalvik Executable) অ্যাপ্লিকেশনের সমস্ত ক্লাসের একটি সংকুচিত উপস্থাপনা ধারণ করে। ফাইল হেডারে চেকসাম, সেকশনের আকার এবং অফসেট অন্তর্ভুক্ত থাকে। প্রধান সেকশনগুলি হল স্ট্রিং, টাইপ, মেথড প্রোটোটাইপ, ফিল্ড এবং বাইটকোডের পুল। একটি একক DEX ফাইল 65,536টি পর্যন্ত মেথড সংরক্ষণ করতে পারে (Android 5.0-এ মাল্টি-ডেক্স প্রবর্তনের সাথে সীমা সরানো হয়েছে)।
Android SDK Build Tools-এ অন্তর্ভুক্ত dx ইউটিলিটি, class ফাইলগুলিকে DEX-এ রূপান্তর করতে ব্যবহৃত হয়। কমান্ডের উদাহরণ: dx --dex --output=classes.dex myapp.jar. আধুনিক প্রকল্পগুলি D8 ব্যবহার করে, যা উন্নত অপ্টিমাইজেশন এবং Java 8+ বৈশিষ্ট্যগুলির সমর্থন সহ dx-এর উত্তরসূরি।
# dx ব্যবহার করে JAR-কে DEX-এ রূপান্তর
dx --dex --output=classes.dex myapp.jar
# D8-এর মাধ্যমে আধুনিক সংস্করণ
d8 --lib android.jar --output dex/ myapp.jar
Zygote প্রক্রিয়াটি Dalvik আর্কিটেকচারের একটি গুরুত্বপূর্ণ উপাদান। সিস্টেম শুরু হলে, Zygote সমস্ত Android SDK ক্লাস লোড করে, শেয়ার্ড লাইব্রেরি খোলে এবং প্রিলোডেড রিসোর্সের একটি পুল তৈরি করে। যখন একজন ব্যবহারকারী একটি অ্যাপ্লিকেশন খোলেন, সিস্টেম Zygote প্রক্রিয়াটি ফর্ক করে, পূর্বে আরম্ভ করা ফ্রেমওয়ার্ক সহ একটি নতুন Dalvik VM ইনস্ট্যান্স তৈরি করে। এটি অ্যাপ্লিকেশন লঞ্চের সময় ~2–3 সেকেন্ড থেকে 300–500 মিলিসেকেন্ডে কমিয়ে আনে।
JIT (Just-In-Time) অ্যাপ্লিকেশন নির্বাহের সময় সরাসরি বাইটকোডকে মেশিন নির্দেশে কম্পাইল করার একটি প্রযুক্তি। Dalvik-এ, JIT কম্পাইলার নির্বাহিত DEX কোড বিশ্লেষণ করে, ঘন ঘন ব্যবহৃত (হট) মেথডগুলি চিহ্নিত করে এবং সেগুলিকে CPU-র জন্য নেটিভ কোডে কম্পাইল করে।
প্রারম্ভিক Android সংস্করণগুলিতে সম্পূর্ণ Ahead-Of-Time (AOT) কম্পাইলেশনের পরিবর্তে JIT-এর নির্বাচন ইচ্ছাকৃত ছিল। মোবাইল ডিভাইসগুলিতে সীমিত ফ্ল্যাশ স্টোরেজ (4–16 GB) ছিল — সমস্ত অ্যাপ্লিকেশন প্রি-কম্পাইল করলে উল্লেখযোগ্য স্থান নিত। এছাড়াও, প্রারম্ভিক ডিভাইসগুলিতে ROM মেমরি RAM-এর চেয়ে ধীর ছিল এবং প্রি-কম্পাইলড কোড পড়া কর্মক্ষমতা হ্রাস করতে পারত।
যখন একটি অ্যাপ্লিকেশন শুরু হয়, Dalvik DEX বাইটকোড ব্যাখ্যা করা শুরু করে। একটি বিশেষ প্রোফাইলার ট্র্যাক করে কোন মেথডগুলি সবচেয়ে বেশি কল করা হয়। একটি থ্রেশহোল্ড (সাধারণত ~200 কল) অতিক্রম করার পর, JIT কম্পাইলার মেথডটিকে মেশিন কোডে রূপান্তর করে এবং RAM-এ ক্যাশ করে। পরবর্তী কলগুলি পুনরায় কম্পাইলেশন ছাড়াই ইতিমধ্যে কম্পাইলড সংস্করণ ব্যবহার করে।
// একটি হট মেথডের উদাহরণ যা JIT কম্পাইল করবে
public class Calculator {
public int sumArray(int[] arr) {
int total = 0;
for (int i = 0; i < arr.length; i++) {
total += arr[i];
}
return total;
}
}
Google I/O 2013-এর মতে, Android 2.2 Froyo-তে JIT-এর প্রবর্তন বিশুদ্ধ ব্যাখ্যার তুলনায় অ্যাপ্লিকেশন নির্বাহ গড়ে 2–5 গুণ ত্বরান্বিত করেছে। তবে, JIT প্রথম লঞ্চে বিলম্ব যোগ করে: একটি অ্যাপ্লিকেশনের ওয়ার্ম আপ এবং হট মেথড কম্পাইল করতে 3 থেকে 10 সেকেন্ড প্রয়োজন। ওয়ার্ম-আপের পরে, কর্মক্ষমতা নেটিভ কোডের কাছাকাছি স্তরে স্থিতিশীল হয়।
Dalvik বিভিন্ন মৌলিক দিক থেকে JVM থেকে ভিন্ন। প্রথম — আর্কিটেকচার: JVM স্ট্যাক-ভিত্তিক, Dalvik রেজিস্টার-ভিত্তিক। দ্বিতীয় — বাইটকোড ফরম্যাট: JVM class ফাইল ব্যবহার করে, Dalvik DEX ব্যবহার করে। তৃতীয় — মেমরি ব্যবস্থাপনা: Dalvik মোবাইল ডিভাইসের সীমিত RAM-এর জন্য অপ্টিমাইজড।
উভয় পদ্ধতিরই শক্তি রয়েছে। স্ট্যাক-ভিত্তিক JVM নির্দেশ সংরক্ষণের জন্য কম জায়গা প্রয়োজন — প্রতিটি নির্দেশ ছোট কারণ অপারেন্ডগুলি স্ট্যাক থেকে অন্তর্নিহিতভাবে নেওয়া হয়। রেজিস্টার-ভিত্তিক Dalvik প্রতি অপারেশনে কম নির্দেশ নির্বাহ করে, যা CPU সময় বাঁচায় এবং বিদ্যুৎ খরচ কমায়। ব্যাটারি-চালিত মোবাইল ডিভাইসের জন্য, এটি গুরুত্বপূর্ণ।
| প্যারামিটার | Dalvik | JVM |
|---|---|---|
| আর্কিটেকচার | রেজিস্টার-ভিত্তিক | স্ট্যাক-ভিত্তিক |
| বাইটকোড | DEX | class |
| কম্পাইলেশন | JIT (Android 2.2+) | JIT / AOT |
| অপ্টিমাইজেশন | কম বিদ্যুৎ খরচ | উচ্চ সামঞ্জস্য |
| বিচ্ছিন্নতা | Linux প্রক্রিয়ার মাধ্যমে | ClassLoader-এর মাধ্যমে |
JVM-এর পরিবর্তে Dalvik-এর নির্বাচন লাইসেন্সিং দ্বারাও পরিচালিত ছিল। Oracle-এর Java SE এবং JVM-এর অধিকার রয়েছে এবং Google লাইসেন্সিং ফি এড়াতে চেয়েছিল। বিকল্প বাইটকোড ফরম্যাট সহ নিজস্ব VM তৈরি Android-কে Oracle-এর থেকে স্বাধীনভাবে বিকাশ করতে দিয়েছে। এই বিরোধ একটি দীর্ঘ আইনি লড়াইয়ে পরিণত হয়েছিল, Oracle বনাম Google (2010–2021), যা Google-এর পক্ষে শেষ হয়েছিল।
DEX (Dalvik Executable) একটি বাইনারি ফরম্যাট যা একটি Android অ্যাপ্লিকেশনের কম্পাইলড কোড ধারণ করে। প্রতিটি DEX ফাইল একটি হেডার দিয়ে শুরু হয়, যার পরে সেকশনগুলি আসে: স্ট্রিং কনস্ট্যান্ট (string_ids), টাইপ (type_ids), মেথড প্রোটোটাইপ (proto_ids), ফিল্ড (field_ids), মেথড (method_ids), ক্লাস ডেফিনিশন (class_defs) এবং একটি ডেটা এলাকা।
dx ইউটিলিটি জাভা class ফাইলগুলিকে এক বা একাধিক DEX ফাইলে রূপান্তর করে। অ্যালগরিদমে কনস্ট্যান্ট ডিডুপ্লিকেশন অন্তর্ভুক্ত — অভিন্ন স্ট্রিং বা টাইপ একবার সংরক্ষণ করা হয় এবং সূচক দ্বারা উল্লেখ করা হয়। এটি চূড়ান্ত আকার উল্লেখযোগ্যভাবে হ্রাস করে। আধুনিক প্রকল্পগুলিতে, dx D8 (Android Studio 3.1-এ প্রবর্তিত) দ্বারা প্রতিস্থাপিত হয়েছে, যা 2–3 গুণ দ্রুত এবং Java 8 ডিসুগারিং সমর্থন করে।
// dexdump-এর মাধ্যমে ডিকম্পাইলড DEX বাইটকোডের উদাহরণ
// সোর্স কোড: return a + b;
@Ldalvik/annotation/Code;
registers: 3
add-int v0, v1, v2
return v0
65,536 মেথডের DEX ফরম্যাট সীমা (16-বিট সূচক সীমা) বড় অ্যাপ্লিকেশনের জন্য একটি গুরুতর সমস্যা হয়ে দাঁড়িয়েছিল। সমাধান Android 5.0-এর সাথে এসেছিল: মাল্টি-ডেক্স সমর্থন একটি অ্যাপ্লিকেশনকে একাধিক DEX ফাইল ধারণ করতে দেয়। প্রধান classes.dex-এ এন্ট্রি পয়েন্ট থাকে, যখন অতিরিক্ত classes2.dex, classes3.dex এবং আরও অনেক কিছু বাকি কোড ধারণ করে। মাল্টি-ডেক্স কনফিগারেশন build.gradle-এ multiDexEnabled true লাইন দিয়ে সক্রিয় করা হয়।
Dalvik-এ আবর্জনা সংগ্রহ মার্ক-এন্ড-সুইপ সহ একটি জেনারেশনাল কালেক্টর হিসাবে বাস্তবায়িত। মেমরি দুটি প্রধান এলাকায় বিভক্ত: অবজেক্টের জন্য Heap এবং প্রিমিটিভ এবং রেফারেন্সের জন্য Stack। যখন Heap পূর্ণ হয়, Dalvik সমস্ত থ্রেড স্থগিত করে (STW — Stop-The-World), অ্যাক্সেসযোগ্য অবজেক্টগুলি চিহ্নিত করে এবং অপ্রাপ্যগুলিকে মুক্ত করে।
Android 2.2-এর আগে, Dalvik 100–200 ms পর্যন্ত বিরতি সময়কাল সহ একটি একক-থ্রেডেড কালেক্টর ব্যবহার করত। Android 2.3 Gingerbread একটি সমবর্তী কালেক্টর প্রবর্তন করেছিল যা সাধারণ বিরতিগুলি 5–10 ms-এ কমিয়েছিল। এবং Android 4.0 Ice Cream Sandwich একটি ইনক্রিমেন্টাল ক্লিনিং সহ একটি কালেক্টর যোগ করেছিল — Concurrent Mark and Sweep (CMS).
Dalvik অ্যাপ্লিকেশনের একটি সাধারণ সমস্যা হল Activity-তে স্ট্যাটিক রেফারেন্সের মাধ্যমে মেমরি লিক। যদি একটি স্ট্যাটিক ফিল্ড Context বা View-এর রেফারেন্স ধরে রাখে, তবে আবর্জনা কালেক্টর স্ক্রিন বন্ধ হওয়ার পরেও Activity মুক্ত করতে পারে না। Eclipse MAT এবং LeakCanary-এর মতো টুলগুলি এই ধরনের লিক সনাক্ত করতে সাহায্য করে: তারা Heap ডাম্প বিশ্লেষণ করে এবং অবজেক্টটি ধরে রাখা রেফারেন্স চেইন দেখায়।
// স্ট্যাটিক রেফারেন্সের মাধ্যমে মেমরি লিকের উদাহরণ
public class Utils {
private static Context context;
public static void init(Context ctx) {
context = ctx; // finish()-এর পর Activity ধরে রাখে
}
}
সাফল্য সত্ত্বেও, Dalvik-এর বেশ কয়েকটি ত্রুটি ছিল। JIT কম্পাইলেশনের ওয়ার্ম-আপ সময় প্রয়োজন ছিল — অ্যাপ্লিকেশন অপারেশনের প্রথম সেকেন্ডগুলি ধীর ছিল। এছাড়াও, JIT কম্পাইলেশনের সময় CPU শক্তি খরচ করত, যা ব্যাটারির আয়ু কমিয়ে দিত। মোবাইল ডিভাইসের কর্মক্ষমতা বাড়ার এবং অন্তর্নির্মিত স্টোরেজ বৃদ্ধি পাওয়ার সাথে সাথে JIT-এর প্রয়োজনীয়তা হ্রাস পেয়েছে।
Android 4.4 KitKat-এ, Google Dalvik-এর পরীক্ষামূলক প্রতিস্থাপন হিসাবে ART (Android Runtime) চালু করেছিল। Android 5.0 Lollipop থেকে শুরু করে, ART একমাত্র রানটাইম পরিবেশ হয়ে ওঠে। প্রধান পার্থক্য হল AOT কম্পাইলেশন: নির্বাহের সময় কম্পাইল করার পরিবর্তে, সমস্ত অ্যাপ্লিকেশন ইনস্টলেশনের সময় মেশিন কোডে কম্পাইল হয়। এটি ওয়ার্ম-আপ বিলম্ব দূর করেছে এবং শক্তি দক্ষতা উন্নত করেছে।
Dalvik থেকে ART-তে রূপান্তর ডেভেলপারদের জন্য স্বচ্ছ ছিল: উভয় রানটাইম একই DEX বাইটকোড নির্বাহ করে। Dalvik-এর জন্য কম্পাইলড অ্যাপ্লিকেশনগুলি পুনরায় কম্পাইলেশন ছাড়াই ART-তে চলে — system_server ইনস্টলেশনের সময় সেগুলিকে নেটিভ কোডে কম্পাইল করে। ব্যতিক্রম হল কোড যা Dalvik VM-এর অভ্যন্তরীণ সদস্যদের অ্যাক্সেস করতে রিফ্লেকশন ব্যবহার করে: এই ধরনের কোড অভ্যন্তরীণ আর্কিটেকচারের পরিবর্তনের কারণে ART-তে ভেঙে যেতে পারে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Dalvik একটি মধ্যস্থতাকারী প্রোগ্রাম যা ফোনে Android অ্যাপ্লিকেশন চালায়। এটি অ্যাপ্লিকেশন কোড নেয় এবং এটিকে প্রসেসরের জন্য বোধগম্য কমান্ডে রূপান্তর করে, ব্যবহারকারী কাজ করার সময় সরাসরি এটি করে।
Dalvik একটি রেজিস্টার-ভিত্তিক আর্কিটেকচার এবং DEX ফরম্যাট ব্যবহার করে, যখন JVM একটি স্ট্যাক-ভিত্তিক আর্কিটেকচার এবং class ফরম্যাট ব্যবহার করে। Dalvik সীমিত মেমরি এবং প্রসেসিং ক্ষমতা সহ মোবাইল ডিভাইসের জন্য অপ্টিমাইজড, যখন JVM ডেস্কটপ কম্পিউটার এবং সার্ভারের জন্য ডিজাইন করা হয়েছে।
ART পূর্ববর্তী AOT কম্পাইলেশনের মাধ্যমে উচ্চতর কর্মক্ষমতা প্রদান করে — অ্যাপ্লিকেশনটি প্রতিবার শুরু হওয়ার সময় নয়, ইনস্টলেশনের সময় একবার কম্পাইল হয়। এটি অপারেশনকে গতি দেয় এবং Dalvik-এর JIT পদ্ধতির তুলনায় ব্যাটারি বাঁচায়।
হ্যাঁ, ART Dalvik DEX বাইটকোডের সাথে সম্পূর্ণ পশ্চাদগামী সামঞ্জস্যপূর্ণ। ইনস্টলেশনের সময়, ART পুরানো DEX ফাইলগুলিকে নেটিভ কোডে কম্পাইল করে। ব্যতিক্রম হল অ্যাপ্লিকেশনগুলি যা Dalvik অভ্যন্তরীণ প্রক্রিয়াগুলি অ্যাক্সেস করতে রিফ্লেকশন ব্যবহার করে।
DEX (Dalvik Executable) একটি নির্বাহযোগ্য ফাইল ফরম্যাট যা একটি Android অ্যাপ্লিকেশনের সংকুচিত বাইটকোড ধারণ করে। একটি APK-তে একাধিক DEX ফাইল (মাল্টি-ডেক্স) থাকতে পারে যদি অ্যাপ্লিকেশনটিতে 65,536-এর বেশি মেথড থাকে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন