Zaimplementuj kompilator ART just-in-time

Środowisko wykonawcze systemu Android (ART) zawiera kompilator just-in-time (JIT) z profilowaniem kodu, który stale poprawia wydajność działających aplikacji systemu Android. Kompilator JIT stanowi uzupełnienie obecnego kompilatora AOT (Aot) firmy ART i poprawia wydajność środowiska wykonawczego, oszczędza miejsce w pamięci oraz przyspiesza aktualizacje aplikacji i systemów. Ulepsza także kompilator AOT, unikając spowolnienia systemu podczas automatycznych aktualizacji aplikacji lub rekompilacji aplikacji podczas aktualizacji OTA.

Chociaż JIT i AOT używają tego samego kompilatora z podobnym zestawem optymalizacji, wygenerowany kod może nie być identyczny. JIT korzysta z informacji o typie środowiska wykonawczego, może lepiej wykonywać wstawianie i umożliwia kompilację z zamianą stosu (OSR), a wszystko to generuje nieco inny kod.

Architektura JIT

Architektura JIT
Rysunek 1. Architektura JIT.

Kompilacja JIT

Kompilacja JIT obejmuje następujące działania:

Kompilacja oparta na profilu
Rysunek 2. Kompilacja oparta na profilu.
  1. Użytkownik uruchamia aplikację, która następnie uruchamia ART w celu załadowania pliku .dex .
    • Jeśli plik .oat (plik binarny AOT dla pliku .dex ) jest dostępny, ART używa go bezpośrednio. Chociaż pliki .oat są generowane regularnie, nie zawsze zawierają skompilowany kod (plik binarny AOT).
    • Jeśli plik .oat nie zawiera skompilowanego kodu, ART uruchamia JIT i interpreter, aby wykonać plik .dex .
  2. JIT jest włączony dla każdej aplikacji, która nie jest skompilowana zgodnie z filtrem kompilacji speed (który mówi „skompiluj tyle, ile możesz z aplikacji”).
  3. Dane profilu JIT są zrzucane do pliku w katalogu systemowym, do którego dostęp ma tylko aplikacja.
  4. Demon kompilacji AOT ( dex2oat ) analizuje ten plik w celu przeprowadzenia kompilacji.

    Demon JIT
    Rysunek 3. Działania demona JIT.

Usługa Google Play jest przykładem używanym przez inne aplikacje, które zachowują się podobnie do bibliotek współdzielonych.

Przepływ pracy JIT

Architektura JIT
Rysunek 4. Przepływ danych JIT.
  • Informacje profilowane są przechowywane w pamięci podręcznej kodu i poddawane procesowi wyrzucania elementów bezużytecznych pod presją pamięci.
    • Nie ma gwarancji, że migawka wykonana, gdy aplikacja działała w tle, będzie zawierać pełne dane (tj. wszystko, co zostało poddane JIT).
    • Nie próbuje się upewnić, że wszystko zostało zarejestrowane (ponieważ może to mieć wpływ na wydajność środowiska wykonawczego).
  • Metody mogą znajdować się w trzech różnych stanach:
    • interpretowane (kod dex)
    • JIT skompilowany
    • Skompilowano AOT
    Jeśli istnieje zarówno kod JIT, jak i AOT (np. z powodu powtarzających się deoptymalizacji), preferowany jest kod JITed.
  • Wymagana pamięć do uruchomienia JIT bez wpływu na wydajność aplikacji na pierwszym planie zależy od danej aplikacji. Duże aplikacje wymagają więcej pamięci niż małe aplikacje. Ogólnie rzecz biorąc, duże aplikacje stabilizują się na poziomie około 4 MB.

Włącz rejestrowanie JIT

Aby włączyć rejestrowanie JIT, uruchom następujące polecenia:

adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start

Wyłącz JIT-a

Aby wyłączyć JIT, uruchom następujące polecenia:

adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start

Wymuś kompilację

Aby wymusić kompilację, uruchom następujące polecenie:

adb shell cmd package compile

Typowe przypadki użycia wymuszania kompilacji określonego pakietu:

  • Oparte na profilu:
    adb shell cmd package compile -m speed-profile -f my-package
    
  • Pełny:
    adb shell cmd package compile -m speed -f my-package
    

Typowe przypadki użycia wymuszania kompilacji wszystkich pakietów:

  • Oparte na profilu:
    adb shell cmd package compile -m speed-profile -f -a
    
  • Pełny:
    adb shell cmd package compile -m speed -f -a
    

Wyczyść dane profilu

Aby wyczyścić dane profilu i usunąć skompilowany kod, uruchom następujące polecenie:

  • Dla jednego pakietu:
    adb shell cmd package compile --reset my-package
    
  • Dla wszystkich pakietów:
    adb shell cmd package compile --reset -a