DEX: چیست، ساختار و原理 کار بایت‌کد

نویسنده: IT Sectr منتشر شده: 2026-04-15 زمان مطالعه: 8 دقیقه

DEX (Dalvik Executable) فرمت بایت‌کدی است که کد منبع برنامه‌های Android به زبان Java و Kotlin به آن کامپایل می‌شود. فایل‌های DEX توسط ماشین مجازی Dalvik (تا Android 4.4) یا Android Runtime (ART، از Android 5.0) اجرا می‌شوند. طبق داده‌های Android Open Source Project، 2026، فرمت DEX به طور متوسط 30% نمایش فشرده‌تری از کد در مقایسه با بایت‌کد استاندارد JVM ارائه می‌دهد.

نکات اصلی

  • DEX — فرمت بایت‌کد برای Android، قابل اجرا روی Dalvik یا ART.
  • فشردگی — DEX 30% کمتر از بایت‌کد استاندارد Java فضا اشغال می‌کند.
  • Multidex — مکانیزمی برای عبور از محدودیت 65536 متد در یک فایل DEX.
  • ART — Android Runtime، جایگزین Dalvik، DEX را هنگام نصب به کد بومی کامپایل می‌کند.
  • D8 — کامپایلر مدرن Java/Kotlin به DEX، جایگزین DX از سال 2018.

DEX چیست و چرا به آن نیاز داریم

DEX (Dalvik Executable) فرمت بایت‌کدی است که به طور خاص برای دستگاه‌های موبایل Android طراحی شده است. برخلاف بایت‌کد استاندارد Java (فایل‌های .class)، DEX برای منابع محدود بهینه شده است: حافظه کمتر، اندازه کوچک‌تر و بارگذاری سریع‌تر کلاس‌ها.

از Java تا DEX

کد منبع به زبان Java یا Kotlin توسط javac/kotlinc به فایل‌های استاندارد .class (بایت‌کد Java) کامپایل می‌شود. سپس ابزار d8 (یا قبلاً dx) فایل‌های .class را به یک یا چند فایل DEX تبدیل می‌کند. این تبدیل صرفاً بسته‌بندی مجدد نیست — d8 بهینه‌سازی‌هایی انجام می‌دهد: ادغام پلت‌های ثابت، بازنویسی دستورالعمل‌ها به معماری ثبتی و حذف داده‌های تکراری.

ویژگی‌های معماری

DEX از معماری ثبتی استفاده می‌کند (برخلاف معماری پشته‌ای JVM). هر متد تعداد ثابت ثبات دارد (تا 65536). دستورالعمل‌های DEX کوتاه‌تر هستند — به طور متوسط 2 بایت در مقابل 1–4 بایت در JVM. این کد فشرده‌تری تولید می‌کند: یک برنامه معمولی از 10–15 MB .class به 4–6 MB .dex کاهش می‌یابد.

ساختار فایل DEX: بخش‌ها و هدر

فایل DEX ساختار باینری کاملاً مشخصی دارد. هر فایل با هدر شروع می‌شود و شامل چندین بخش است که از طریق افست به یکدیگر ارجاع می‌دهند.

بخشهدف
headerهدر: magic، جمع کنترلی، امضا، اندازه‌ها و افست بخش‌ها
string_idsجدول رشته‌ها: نام کلاس‌ها، متدها، فیلدها
type_idsانواع: ارجاع به شناسه‌های رشته‌ای انواع
proto_idsپروتوتایپ متدها: نوع بازگشتی و پارامترها
field_idsفیلدهای کلاس: کلاس، نوع، نام
method_idsمتدها: کلاس، پروتوتایپ، نام
class_defsتعاریف کلاس: پرچم‌ها، superclass، interface‌ها، افست داده
dataداده‌های واقعی: کد متدها، حاشیه‌نویسی‌ها، اطلاعات debug

هدر DEX

عدد جادویی DEX — `dex\n035\0` (نسخه 035). نسخه‌های دیگر: 036، 037، 038 (برای Android 8.0+). هدر با اندازه 0x70 بایت شامل جمع کنترلی SHA-1 و افست تمام بخش‌ها است. اعتبارسنجی هدر — اولین گام هنگام بارگذاری DEX توسط ماشین مجازی.

پلت‌های ثابت

string_ids، type_ids، proto_ids، field_ids، method_ids — جدول‌های ایندکس شده هستند. به جای ذخیره نام‌های کامل در کد متد، از ایندکس 4 بایتی استفاده می‌شود. این بهینه‌سازی کلیدی است: اگر کلاس 100 بار ذکر شود، نام آن یک بار در string_ids ذخیره می‌شود. dex2oat در هنگام کامپایل ART این جدول‌ها را بیشتر بهینه می‌کند.

فرآیند کامپایل Java و Kotlin به DEX

فرآیند تبدیل کد منبع به DEX از چند مرحله تشکیل شده است. زنجیره مدرن از کامپایلر D8 استفاده می‌کند که در سال 2018 با Android Gradle Plugin 3.2 جایگزین DX شد.

مرحله 1: کامپایل به .class

javac (برای Java) یا kotlinc (برای Kotlin) کد منبع را به فایل‌های .class کامپایل می‌کنند. هر کلاس — یک فایل .class جداگانه در بایت‌کد Java. در این مرحله بررسی نوع، تولید متدهای bridge و جاسازی ثابت‌ها انجام می‌شود.

مرحله 2: کامپایل D8

D8 تمام فایل‌های .class را دریافت کرده و به بایت‌کد DEX تبدیل می‌کند. D8 چندین بهینه‌سازی انجام می‌دهد: حذف آرگومان‌های استفاده نشده متدها، ادغام پلت‌های ثابت از .classهای مختلف در یک پلت سراسری DEX، تبدیل دستورالعمل‌های پشته‌ای JVM به دستورالعمل‌های ثبتی Dalvik.

kotlin
// کد منبع Kotlin
data class User(
    val name: String,
    val email: String
)

fun greet(user: User): String {
    return "Hello, ${user.name}!"
}

پس از کامپایل D8، این کد به دستورالعمل‌های فشرده DEX تبدیل می‌شود: const-string برای بارگذاری رشته، iget-object برای دسترسی به فیلد شیء، invoke-virtual برای فراخوانی StringBuilder.append.

D8 در مقابل DX

D8 2–3 برابر سریع‌تر از DX کار می‌کند، DEX فشرده‌تری تولید می‌کند (5–10%) و ساختارهای خاص Kotlin (توابع inline، lambda) را بهتر بهینه می‌کند. DX از سال 2018 منسوخ (deprecated) اعلام شده و از Android Gradle Plugin 8.0 حذف شده است.

Dalvik در مقابل ART: تغییر اجرای DEX

اجرای کد DEX در Android دو مرحله را طی کرده است: ماشین مجازی اصلی Dalvik (Android 2.2–4.4) و Android Runtime ART (Android 5.0+). تفاوت در رویکرد کامپایل اساسی است.

Dalvik VM: کامپایل JIT

Dalvik از کامپایل Just-In-Time (JIT) استفاده می‌کرد: بایت‌کد DEX تفسیر می‌شد و متدهای پراستفاده در لحظه به کد بومی کامپایل می‌شدند. مزیت — نصب سریع. عیب — شروع کندتر و مصرف دائمی CPU برای JIT.

ART: کامپایل AOT

ART (Android Runtime) DEX را هنگام نصب برنامه از طریق dex2oat به کد بومی کامپایل می‌کند. این رویکرد Ahead-Of-Time (AOT) است: نصب طولانی‌تر، اما راه‌اندازی سریع‌تر و مصرف انرژی کمتر. از Android 7.0 ART از رویکرد هیبریدی — AOT + JIT + Profile Guided Optimization استفاده می‌کند.

dex2oat: تبدیل هنگام نصب

ابزار dex2oat هنگام نصب یا به‌روزرسانی برنامه اجرا می‌شود. DEX را به فایل ELF با کد بومی برای معماری دستگاه کامپایل می‌کند. نتیجه — فایل‌های .oat و .art در پوشه /data/dalvik-cache/. Google دائماً dex2oat را بهبود می‌بخشد: در Android 14 بهینه‌سازی برای دستگاه‌های تاشو اضافه شده است.

Multidex: غلبه بر محدودیت 64K متد

محدودیت 65536 متد در یک فایل DEX — میراثی از معماری Dalvik. فیلد method_ids در هدر DEX 4 بایت اشغال می‌کند که حداکثر 2^16 = 65536 ارجاع منحصربه‌فرد می‌دهد. برنامه‌های مدرن با Google Play Services، Firebase و سایر SDKها به راحتی این محدودیت را عبور می‌کنند.

مکانیزم Multidex

Multidex مکانیزمی برای تقسیم کد به چندین فایل DEX است. classes.dex اصلی شامل نقاط ورود (کلاس Application، Activityهای اصلی) است، بقیه — classes2.dex، classes3.dex و غیره. هنگام اجرا، کلاس‌های DEX اضافی از طریق DexClassLoader بارگذاری می‌شوند.

kotlin
// build.gradle.kts — فعال‌سازی multidex
android {
    defaultConfig {
        multiDexEnabled = true
    }
}

// کلاس Application با پشتیبانی multidex
class MyApp : Application() {
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
}

مشکلات Multidex

بارگذاری DEX اضافی در مرحله راه‌اندازی برنامه می‌تواند باعث ANR (Application Not Responding) در دستگاه‌های دارای Android تا 5.0 شود. توصیه — فقط در صورت لزوم از multidex استفاده کنید و برای عدم عبور از حد مجاز، وابستگی‌ها را به حداقل برسانید.

بهینه‌سازی DEX: ProGuard، R8 و مبهم‌سازی

بهینه‌سازی DEX — مرحله استاندارد ساخت نسخه release برنامه Android. ابزارهای R8 و ProGuard اندازه DEX را کاهش می‌دهند، کد را مبهم می‌کنند و کلاس‌های استفاده نشده را حذف می‌کنند.

R8 در مقابل ProGuard

R8 — جانشین ProGuard، از سال 2019 در Android Gradle Plugin تعبیه شده است. R8 کوچک‌سازی، مبهم‌سازی و بهینه‌سازی را در یک پاس انجام می‌دهد، در حالی که ProGuard به دو مرحله نیاز داشت: ProGuard → D8. ProGuard هنوز پشتیبانی می‌شود، اما Google برای پروژه‌های جدید R8 را توصیه می‌کند.

R8 کلاس‌ها، متدها و فیلدهای استفاده نشده را حذف می‌کند، نام‌های آنها را به نام‌های کوتاه (a، b، c) تغییر می‌دهد، توابع inline را جاسازی می‌کند و کد مرده را دور می‌ریزد. نتیجه — DEX بدون از دست دادن عملکرد 20–40% کاهش می‌یابد.

قوانین R8

پیکربندی R8 در فایل proguard-rules.pro تعریف می‌شود. توسعه‌دهنده می‌تواند مشخص کند کدام کلاس‌ها نباید تغییر نام دهند (مثلاً برای بازتاب یا سریال‌سازی Gson). Firebase و سایر SDKها قوانین خود را در وابستگی‌های خود ارائه می‌دهند.

دکامپایل DEX: ابزارها و محافظت

DEX را می‌توان دوباره به کد Java دکامپایل کرد. این موضوع کلیدی امنیت برنامه‌های Android است: بدون مبهم‌سازی، کد تا سطح نزدیک به اصلی بازسازی می‌شود.

ابزارهای دکامپایل

JADX — محبوب‌ترین دکامپایلر DEX به Java. نام کلاس‌ها، متدها، فیلدها و بیشتر منطق را بازسازی می‌کند. apktool DEX را به کد smali (اسمبلر Dalvik) دکامپایل می‌کند — نمایش سطح پایین نزدیک به دستورالعمل‌های اصلی. Bytecode Viewer چندین دکامپایلر را در یک رابط ترکیب می‌کند.

روش‌های محافظت

مبهم‌سازی R8/ProGuard — خط اول دفاع: نام کلاس‌ها و متدها غیرقابل خواندن می‌شوند. DexGuard — ابزار تجاری با روش‌های اضافی: رمزگذاری رشته‌ها، بررسی یکپارچگی، ضد دستکاری. مبهم‌سازی در سطح Control Flow (O-LLVM) ساختار کد را تغییر می‌دهد، عملکرد آن را حفظ می‌کند اما تحلیل را بسیار دشوارتر می‌سازد.

سوالات متداول

DEX چه تفاوتی با بایت‌کد Java دارد؟

DEX به جای معماری پشته‌ای JVM از معماری ثبتی استفاده می‌کند، فرمت فشرده‌تری دارد (30% کوچک‌تر)، تمام فایل‌های .class را در یک فایل با پلت ثابت واحد ترکیب می‌کند و به جای ایندکس‌های 8 بیتی از ایندکس‌های 16 بیتی استفاده می‌کند.

Smali چیست؟

Smali — اسمبلر بایت‌کد DEX است. هر دستورالعمل DEX یک نمایش متنی در قالب smali دارد. ابزار baksmali DEX را به smali تبدیل می‌کند (دی‌اسمبلی)، و smali اسمبلی را دوباره به DEX می‌سازد.

چگونه تعداد متدها را در DEX بررسی کنیم؟

Gradle task countMethods یا پلاگین dex-method-counts تعداد متدها را در هر فایل DEX نشان می‌دهد. دستور adb shell با dumpsys نیز آمار DEX بارگذاری شده برای برنامه‌های نصب شده را نمایش می‌دهد.

آیا تعداد DEX بر عملکرد تأثیر می‌گذارد؟

بله، در دستگاه‌های دارای Android تا 8.0، DEX چندگانه راه‌اندازی برنامه را کند می‌کند زیرا هر فایل اضافی جداگانه بارگذاری می‌شود. در ART با Android 8.0+ تفاوت حداقل است به دلیل کامپایل dex2oat به یک فایل .oat واحد.

آیا می‌توان DEX را بدون Android اجرا کرد؟

بله، پروژه‌هایی مانند dexplorer و پیاده‌سازی‌های JVM سازگار با Android وجود دارند که می‌توانند بایت‌کد DEX را خارج از Android اجرا کنند. با این حال، بیشتر فایل‌های DEX از Android API استفاده می‌کنند که آنها را برای اجرا روی JVM معمولی نامناسب می‌کند.

خلاصه

  • DEX — فرمت بایت‌کد Android با معماری ثبتی و نمایش فشرده کد.
  • ساختار شامل هدر، جدول‌های شناسه و بخش داده با دستورالعمل‌ها است.
  • کامپایل به DEX از طریق D8 انجام می‌شود: .class → DEX با بهینه‌سازی و ادغام پلت‌های ثابت.
  • ART DEX را هنگام نصب به کد بومی کامپایل می‌کند (AOT) و راه‌اندازی برنامه را تسریع می‌بخشد.
  • Multidex — راه‌حل مشکل محدودیت 65536 متد از طریق تقسیم به چندین فایل DEX.
  • بهینه‌سازی — R8 DEX را 20–40% کاهش می‌دهد، نام‌ها را مبهم می‌کند و کد مرده را حذف می‌کند.
  • محافظت — مبهم‌سازی R8/ProGuard، DexGuard و O-LLVM از دکامپایل DEX جلوگیری می‌کند.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید