Virtual maşın Dalvik — Android əməliyyat sisteminin açar komponenti, 4.4 KitKat versiyasına qədər tətbiqlɘrin icrasına cavabdeh idi. Dan Bornşteyn tərəfindən hazırlanmış registr VM standart JVM konsepsiyasını əvəz etdi və məhdud RAM həcmi olan mobil cihazlarda tətbiqlɘrin işə salınmasını optimallaşdırmağa imkan verdi. Google, 2024 məlumatlarına görə, Dalvik JIT-kompilyasiyası vasitəsilə tətbiqlɘrin uyğunluğunu təmin edirdi, DEX-bayt-kodunu icra zamanı birbaşa maşın təlimatlarına çevirirdi.
Əsas məqamlar
Dalvik — xüsusilɘ Android platforması üçün yaradılmış registr arxitekturalı virtual maşın. İşlɘnmə 2005-ci ildə Dan Bornşteynin şirkətindɘ başladı, 2007-ci ildɘ isɘ layihɘ Google tərəfindən satın alındı. Dalvik-in ilk kommersiya versiyası 2008-ci ildɘ Android 1.0 buraxılışı ilɘ birlikdɘ ortaya çıxdı.
Standart Java Virtual Machine-dɘn (JVM) fərqli olaraq, Dalvik Java-bayt-kodunu icra etmir. Java kompilyatoru mənbɘ kodunu class-fayllara çevirir, sonra isɘ dx aləti onları Dalvik Executable (DEX) formatına tərcümə edir. Bu format class-fayllardan daha yığcamdır: class formatında 10 MB olan bir tətbiq DEX-dɘ təxminɘn 6–7 MB yer tutur.
Dan Bornşteyn Dalvik-i məhdud resurslu əməliyyat sistemlɘri üçün bir layihɘ olaraq yazdı. Adı Islandiyanın Dalvík kəndindɘn götürülmüşdür. Google lisenziya məhdudiyyɘtlɘri və ARM arxitekturası olan mobil prosessorlar üçün dərin optimallaşdırma ehtiyacı səbɘbindɘn JVM əvɘzinɘ Dalvik-i seçdi. Sistem sürətlɘ populyarlıq qazandı: 2012-ci ilɘ qədɘr 500 milyondan çox Android cihazı Dalvik-dɘ işlɘyirdi.
Hɘr bir Android tətbiqi öz Dalvik VM nüsxɘsi ilɘ ayrı prosesdɘ işə salınır. Bu, əmɘliyyat sistemi sɘviyyɘsindɘ məlumatların izolyasiyasını vɘ zɘrərli koddan qorunmanı təmin edir. Belɘ yanaşma virtualizasiyanın üstünlüklɘrini Linux qum qutusu ilɘ birlɘşdirir — bir tətbiqdɘki zɘrərli proqram qonşu proseslɘrɘ təsir edɘ bilmɘz.
Registr arxitekturası Dalvik JVM-in yığın arxitekturasından prinsipial olaraq fərqlɘnir. Yığının yuxarı hissɘsi ilɘ əmɘliyyatlar əvɘzinɘ, Dalvik registrlɘrlɘ — VM daxilindɘki virtual hücreylɘrlɘ işlɘyir. Hɘr bir təlimat operand registrlɘrinin ünvanlarını ehtiva edir ki, bu da bir əmɘliyyata düşɘn təlimatların sayını azaldır.
JVM yığın maşını push, pop və add kimi təlimatlar istifadɘ edir — iki rəqɘmi toplamaq üçün üç təlimat lazımdır. Dalvik eyni tapşırığı üç registrli bir add-int təlimatı ilɘ hɘll edir. Android Open Source Project məlumatlarına görɘ, DEX-in registr arxitekturası bayt-kodun həcmini yığın class formatı ilɘ müqayisɘdɘ orta hesabla 30% azaldır.
DEX-faylı (Dalvik Executable) tətbiqin bütün siniflɘrinin sıxışdırılmış təsvirini ehtiva edir. Faylın başlığına yoxlama cəmi, bölmƈ ölçülɘri və yerdɘyişmɘlɘr daxildir. Əsas bölmƈlɘr sɘtir hovuzları, tiplɘr, metod prototiplɘri, sahɘlɘr, metodlar vɘ bayt-kodun özüdür. Bir DEX-faylında 65536 metod saxlanıla bilɘr (Android 5.0-dɘ multi-dex tətbiqi ilɘ bu məhdudiyyɘt aradan qaldırılmışdır).
Class-fayllarını DEX-ɘ çevirmɘk üçün Android SDK Build Tools tɘrkibinɘ daxil olan dx alɘtindɘn istifadɘ edilir. Nümunɘ ɘmri: dx --dex --output=classes.dex myapp.jar. Müasir layihɘlɘr təkmillɘşmiş optimallaşdırma və Java 8+ xüsusiyyɘtlɘri dɘstɘyi ilɘ D8 — dx-in varisindɘn istifadɘ edir.
# JAR-ın dx ilɘ DEX-ɘ çevrilmɘsi
dx --dex --output=classes.dex myapp.jar
# Müasir versiya D8 vasitɘsilɘ
d8 --lib android.jar --output dex/ myapp.jar
Zygote prosesi — Dalvik arxitekturasının ən vacib elementidir. Sistem işɘ düşɘrkɘn Zygote Android SDK-nın bütün siniflɘrini yüklɘyir, ümumi kitabxanaları açır vɘ əvvəlcɘdɘn yüklɘnmiş resurslar hovuzu yaradır. İstifadɘçi tətbiqi açdıqda, sistem Zygote prosesini kopyalayır (fork) vɘ hazır freymvorkla yeni Dalvik VM nüsxɘsi yaradır. Bu, tətbiqin işɘ salınma müddɘtini ~2–3 saniyɘdɘn 300–500 millisaniyɘyɘ qədɘr azaldır.
JIT (Just-In-Time) — bayt-kodun maşın təlimatlarına tətbiqin icrası zamanı birbaşa kompilyasiya texnologiyası. Dalvik-dɘ JIT-kompilyatoru icra olunan DEX kodunu təhlil edir, tez-tez istifadɘ olunan (hot) metodları müəyyɘnlɘşdirir və onları CPU üçün nativ koda kompilyasiya edir.
Android-in ilk versiyalarında tam Ahead-Of-Time (AOT) kompilyasiyası əvɘzinɘ JIT seçimi şürurlu idi. Mobil cihazlar məhdud flaş yaddaşa (4–16 GB) malik idi — bütün tətbiqlɘrin əvvəlcɘdɘn kompilyasiyası əhɘmiyyɘtli yer tutardı. Bundan əlavɘ, erkɘn cihazlarda ROM yaddaşı operativ yaddaşdan daha yavaş işlɘyirdi vɘ əvvəlcɘdɘn kompilyasiya edilmiş kodun oxunması performansı aşağı sala bilɘrdi.
Tətbiq işɘ salındıqda, Dalvik DEX-bayt-kodunu interpretasiya etmɘyɘ başlayır. Xüsusi profiler hansı metodların daha tez-tez çağırıldığını izlɘyir. Həddi aşdıqdan sonra (adətɘn ~200 çağırış) JIT-kompilyatoru metodu maşın koduna çevirir və onu RAM-da keşlɘyir. Sonrakı çağırışlar artıq təkrar kompilyasiya olmadan kompilyasiya edilmiş versiyadan istifadɘ edir.
// JIT-in kompilyasiya edɘcɘyi hot-metod nümunɘsi
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 məlumatlarına görɘ, Android 2.2 Froyo-da JIT-in tətbiqi tətbiqlɘrin icrasını təmiz interpretasiya ilɘ müqayisɘdɘ orta hesabla 2–5 dəfɘ sürɘtlɘndirdi. Lakin JIT ilk işɘ salınmada gecikmɘ əlavɘ edir: tətbiqin isinmɘsi və hot-metodların kompilyasiyası üçün 3-dɘn 10 saniyɘyɘ qədɘr vaxt təlɘb olunur. Isindikdɘn sonra performans nativ koda yaxın sɘviyyɘdɘ sabitlɘşir.
Dalvik JVM-dɘn bir neçɘ fundamental parametrɘ görɘ fərqlɘnir. Birincisi — arxitektura: JVM yığınlı, Dalvik registrlidir. İkincisi — bayt-kod formatı: JVM class-fayllarından, Dalvik isɘ DEX-dɘn istifadɘ edir. Üçüncüsu — yaddaşın idarɘ edilmɘsi: Dalvik mobil cihazların məhdud RAM həcmi üçün optimallaşdırılmışdır.
Hɘr iki yanaşmanın güclü tɘrɘflɘri var. Yığınlı JVM təlimatların saxlanması üçün daha az yer təlɘb edir — hɘr bir təlimat daha qısadır, çünki operandlar yığından gizli şɘkildɘ götürülür. Registrli Dalvik bir əmɘliyyata daha az təlimat icra edir ki, bu da prosessor vaxtına qənaət edir və enerji sɘrfini azaldır. Batareya ilɘ işlɘyɘn mobil cihazlar üçün bu kritikdir.
| Parametr | Dalvik | JVM |
|---|---|---|
| Arxitektura | Registrli | Yığınlı |
| Bayt-kod | DEX | class |
| Kompilyasiya | JIT (Android 2.2+) | JIT / AOT |
| Optimallaşdırma | Aşağı enerji sɘrfi | Yüksɘk uyğunluq |
| Izolyasiya | Linux proseslɘri vasitɘsilɘ | ClassLoader vasitɘsilɘ |
JVM əvɘzinɘ Dalvik seçimi hɘm dɘ lisenziyalaşdırma ilɘ bağlı idi. Oracle Java SE vɘ JVM-ɘ hüquqlara sahibdir və Google lisenziya ödɘnişlɘrindɘn qaçmağa çalışırdı. Alternativ bayt-kod formatı ilɘ öz VM-ni yaratmaq Android-ɘ Oracle-dan asılı olmadan inkişaf etmɘyɘ imkan verdi. Bu mübahisɘ Oracle vs Google (2010–2021) arasında uzun illik məhkɘmɘ prosesinɘ çevrildi və Google-ın xeyrinɘ başa çatdı.
DEX (Dalvik Executable) — Android tətbiqinin kompilyasiya edilmiş kodunu ehtiva edɘn ikili format. Hɘr bir DEX-faylı başlıq (header) ilɘ başlayır, ardından bölmƈlɘr gɘlir: sɘtir sabitlɘri (string_ids), tiplɘr (type_ids), metod prototiplɘri (proto_ids), sahɘlɘr (field_ids), metodlar (method_ids), sinif tɘriflɘri (class_defs) və məlumat sahɘsi (data).
dx alɘti Java class-fayllarını bir vɘ ya bir neçɘ DEX-faylına çevirir. İş alqoritmi sabitlɘrin deduplikasiyasını əhatɘ edir — eyni sɘtirlɘr vɘ ya tiplɘr bir dɘfɘ saxlanılır vɘ indekslɘ istinad edilir. Bu, son ölçünü əhɘmiyyɘtli dɘrɘcɘdɘ azaldır. Müasir layihɘlɘrdɘ dx D8 ilɘ (Android Studio 3.1-dɘ ortaya çıxıb) əvɘz edilmişdir, o 2–3 dəfɘ sürɘtli işlɘyir və Java 8 desaqarinqini dɘstɘklɘyir.
// dexdump vasitɘsilɘ dekompilyasiya edilmiş DEX-bayt-kod nümunɘsi
// Mɘnbɘ kodu: return a + b;
@Ldalvik/annotation/Code;
registers: 3
add-int v0, v1, v2
return v0
DEX formatının 65536 metod məhdudiyyɘti (16-bit indeks limiti) böyük tətbiqlɘr üçün ciddi problem halına gɘldi. Hɘll Android 5.0-dɘ ortaya çıxdı: multi-dex dɘstɘyi tətbiqɘ bir neçɘ DEX-faylı daxil etmɘyɘ imkan verir. Əsas classes.dex giriş nöqtɘlɘrini ehtiva edir, əlavɘ classes2.dex, classes3.dex və s. isɘ qalan kodu əhatɘ edir. Multi-dex konfiqurasiyası build.gradle faylında multiDexEnabled true sɘtri ilɘ aktivlɘşdirilir.
Dalvik-dɘ zibil yığımı işaretlɘmɘ vɘ tɘmizlɘmɘ (mark-and-sweep) ilɘ nɘsil (generational) yığıcı kimi héyata keçirilir. Yaddaş iki əsas sahɘyɘ bölünür: obyektlɘr üçün Heap (yığın) vɘ primitivlɘr vɘ istinadlar üçün Stack (yığın). Heap dolduqda Dalvik bütün ipliklɘri dayandırır (STW — Stop-The-World), çatılan obyektlɘri işaretlɘyir vɘ çatılmayanları azad edir.
Android 2.2-yɘ qɘdɘr Dalvik 100–200 ms-ə qɘdɘr fasilɘlɘrlɘ bir iplikli yığıcıdan istifadɘ edirdi. Android 2.3 Gingerbread-dɘ paralel yığıcı ortaya çıxdı, tipik fasilɘlɘri 5–10 ms-ɘ endirdi. Android 4.0 Ice Cream Sandwich-dɘ isɘ hissɘli (incremental) tɘmizlɘmɘ ilɘ yığıcı — Concurrent Mark and Sweep (CMS) əlavɘ edildi.
Dalvik tətbiqlɘrinin tipik problemi — Activity-yɘ statik istinadlar vasitɘsilɘ yaddaş sızıntıları. Statik sahɘ Context vɘ ya View-ɘ istinad saxlayırsa, zibil yığıcısı ekran bağlansa belɘ Activity-ni azad edɘ bilmɘz. Eclipse MAT vɘ LeakCanary kimi alɘtlɘr belɘ sızıntıları aşkarlamağa kömɘk edir: onlar Heap dump-ını tɘhlil edir vɘ obyekti saxlayan istinad zɘncirlɘrini göstɘrir.
// Statik istinad vasitɘsilɘ yaddaş sızıntısı nümunɘsi
public class Utils {
private static Context context;
public static void init(Context ctx) {
context = ctx; // Activity-ni finish()-ən sonra saxlayır
}
}
Uğura baxmayaraq, Dalvik-in bir sıra çatışmazlıqları var idi. JIT-kompilyasiyası isinmə üçün vaxt təlɘb edirdi — tətbiqin ilk saniyɘlɘri daha yavaş idi. Bundan əlavɘ, JIT kompilyasiya zamanı prosessor enerjisi sɘrf edirdi ki, bu da batareyanın iş müddɘtini azaldırdı. Mobil cihazların performansının artması vɘ daxili yaddaş həcminin çoxalması ilɘ JIT-ɘ ehtiyac azaldı.
Android 4.4 KitKat-dɘ Google Dalvik-ɘ eksperimental əvɘz olaraq ART (Android Runtime)-u təqdim etdi. Android 5.0 Lollipop-dan başlayaraq ART yeganə icra mühiti oldu. Əsas fərq — AOT-kompilyasiyası: iş zamanı kompilyasiya əvɘzinɘ, bütün tətbiqlɘr quraşdırma zamanı maşın koduna kompilyasiya edilir. Bu, isinmɘ gecikmɘlɘrini aradan qaldırdı və enerji sɘmɘrɘliliyini yaxşılaşdırdı.
Dalvik-dɘn ART-ə keçid proqramçılar üçün şəffaf oldu: hɘr iki mühit eyni DEX-bayt-kodunu icra edir. Dalvik üçün yığılmış tətbiqlɘr təkrar kompilyasiya olmadan ART-ə işlɘyir — system_server onları quraşdırma zamanı nativ koda kompilyasiya edir. İstisna, Dalvik VM-nin daxili üzvlɘrinɘ daxil olmaq üçün refleksiyadan istifadɘ edɘn koddur: belɘ kod daxili arxitekturanın dɘyişmɘsi sɘbɘbindɘn ART-dɘ işlɘmɘyɘ bilɘr.
Tez-tez verilɘn suallar
Dalvik — telefondakı Android tətbiqlɘrini işə salan vasitɘçi proqramdır. O, tətbiqin kodunu götürür və onu prosessorun başa düşdüyü əmrlɘrɘ çevirir, bunu istifadɘçinin işi zamanı birbaşa edir.
Dalvik registr arxitekturasından və DEX formatından istifadɘ edir, JVM isɘ yığın arxitekturasından və class formatından. Dalvik məhdud yaddaşı və prosessoru olan mobil cihazlar üçün optimallaşdırılıb, JVM isɘ stasionar kompüter və serverlɘr üçün nɘzɘrdɘ tutulub.
ART əvvəlcɘdɘn AOT-kompilyasiyası hesabına daha yüksɘk performans təmin edir — tətbiq hɘr işɘ salınmada yox, quraşdırma zamanı bir dəfɘ kompilyasiya olunur. Bu, Dalvik-in JIT yanaşması ilɘ müqayisɘdɘ işi sürɘtlɘndirir vɘ batareyaya qənaət edir.
Bəli, ART Dalvik-in DEX-bayt-kodu ilɘ tam geriyɘ uyğundur. Quraşdırma zamanı ART köhnɘ DEX-fayllarını nativ koda kompilyasiya edir. İstisna, Dalvik-in daxili mexanizmlɘrinɘ daxil olmaq üçün refleksiyadan istifadɘ edɘn tətbiqlɘrdir.
DEX (Dalvik Executable) — Android tətbiqinin sıxışdırılmış bayt-kodunu ehtiva edɘn icra olunan fayl formatı. Bir APK-da bir neçɘ DEX-faylı (multi-dex) ola bilɘr, əgɘr tətbiq 65536-dan çox metod ehtiva edirsɘ.
Nəticəlɘr
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun