Środowisko wykonawcze Androida (ART) zawiera kompilator JIT (just-in-time) z profilowaniem kodu, który stale poprawia wydajność aplikacji na Androida podczas ich działania. Kompilator JIT uzupełnia obecny kompilator AOT (ahead-of-time) środowiska ART i poprawia wydajność środowiska wykonawczego, oszczędza miejsce na dane i przyspiesza aktualizacje aplikacji i systemu. Poprawia też działanie kompilatora AOT, ponieważ zapobiega spowolnieniu systemu podczas automatycznych aktualizacji aplikacji lub ponownej kompilacji aplikacji podczas aktualizacji OTA (over-the-air).
Chociaż kompilatory JIT i AOT używają tego samego kompilatora z podobnym zestawem optymalizacji, wygenerowany kod może się różnić. Kompilator JIT korzysta z informacji o typach środowiska wykonawczego, może lepiej wstawiać kod i umożliwia kompilację OSR (on stack replacement), co powoduje generowanie nieco innego kodu.
Architektura JIT
Kompilacja JIT
Kompilacja JIT obejmuje te działania:
- Użytkownik uruchamia aplikację, co powoduje, że środowisko ART wczytuje plik
.dex.- Jeśli dostępny jest plik
.oat(binarny plik AOT dla pliku.dex), środowisko ART używa go bezpośrednio. Pliki.oatsą generowane regularnie, ale nie zawsze zawierają skompilowany kod (plik binarny AOT). - Jeśli plik
.oatnie zawiera skompilowanego kodu, środowisko ART uruchamia kompilator JIT i interpreter, aby wykonać plik.dex.
- Jeśli dostępny jest plik
- Kompilator JIT jest włączony w przypadku każdej aplikacji, która nie jest kompilowana zgodnie z filtrem kompilacji
speed(który oznacza „skompiluj jak najwięcej kodu z aplikacji”). - Dane profilu JIT są zapisywane w pliku w katalogu systemowym, do którego dostęp ma tylko aplikacja.
- Demon kompilacji AOT (
dex2oat) analizuje ten plik, aby przeprowadzić kompilację.
Rysunek 3. Działania demona JIT.
Usługa Google Play to przykład używany przez inne aplikacje, które działają podobnie do bibliotek współdzielonych.
Proces JIT
- Informacje o profilowaniu są przechowywane w pamięci podręcznej kodu i podlegają odśmiecaniu w przypadku braku pamięci.
- Nie ma gwarancji, że migawka utworzona, gdy aplikacja działała w tle, będzie zawierać pełne dane (czyli wszystkie dane, które zostały skompilowane przez JIT).
- Nie ma też gwarancji, że wszystkie dane zostaną zarejestrowane (ponieważ może to wpłynąć na wydajność środowiska wykonawczego).
- Metody mogą być w 3 różnych stanach:
- interpretowane (kod dex),
- skompilowane przez JIT,
- skompilowane przez AOT.
- Wymagania dotyczące pamięci do uruchomienia kompilatora JIT bez wpływu na wydajność aplikacji działającej na pierwszym planie zależą od danej aplikacji. Duże aplikacje wymagają więcej pamięci niż małe. Zwykle duże aplikacje stabilizują się na poziomie około 4 MB.
Włączanie logowania JIT
Aby włączyć logowanie JIT, uruchom te polecenia:
adb rootadb shell stopadb shell setprop dalvik.vm.extra-opts -verbose:jitadb shell start
Wyłączanie JIT
Aby wyłączyć JIT, uruchom te polecenia:
adb rootadb shell stopadb shell setprop dalvik.vm.usejit falseadb shell start
Wymuszanie kompilacji
Aby wymusić kompilację, uruchom to polecenie:
adb shell cmd package compile
Typowe przypadki użycia wymuszonej kompilacji konkretnego pakietu:
- Oparte na profilu:
adb shell cmd package compile -m speed-profile -f my-package
- Pełne:
adb shell cmd package compile -m speed -f my-package
Typowe przypadki użycia wymuszonej kompilacji wszystkich pakietów:
- Oparte na profilu:
adb shell cmd package compile -m speed-profile -f -a
- Pełne:
adb shell cmd package compile -m speed -f -a
Czyszczenie danych profilu
W Androidzie 13 lub starszym
Aby wyczyścić lokalne dane profilu i usunąć skompilowany kod, uruchom to polecenie:
adb shell pm compile --reset
W Androidzie 14 lub nowszym
Aby wyczyścić tylko lokalne dane profilu:
adb shell pm art clear-app-profiles
Uwaga: w przeciwieństwie do polecenia w Androidzie 13 lub starszym to polecenie nie czyści zewnętrznych danych profilu (`.dm`), które są instalowane z aplikacją.
Aby wyczyścić lokalne dane profilu i usunąć skompilowany kod wygenerowany na podstawie lokalnych danych profilu (czyli przywrócić stan instalacji), uruchom to polecenie:
adb shell pm compile --reset
Uwaga: to polecenie nie usuwa skompilowanego kodu wygenerowanego na podstawie zewnętrznych danych profilu (`.dm`), które są instalowane z aplikacją.
Aby wyczyścić cały skompilowany kod, uruchom to polecenie:
adb shell cmd package compile -m verify -f
Uwaga: to polecenie zachowuje lokalne dane profilu.