Środowisko wykonawcze Androida (ART) to domyślne środowisko wykonawcze dla urządzeń z Androidem 5.0 (poziom interfejsu API 21) lub nowszy. To środowisko wykonawcze udostępnia wiele funkcji które zwiększają wydajność i płynność działania platformy Androida i aplikacji. Więcej informacji o nowych funkcjach ART znajdziesz w Prezentacjach REKLAMA GRAFICZNA
Jednak niektóre techniki, które działają w Dalviku, nie działają w ART. Ten informuje, na co zwracać uwagę przy migracji istniejącego dokumentu aby była zgodna z ART. Większość aplikacji powinna po prostu działać ART.
Rozwiązywanie problemów z czyszczeniem pamięci
W dziedzinie Dalvik aplikacje często przydają się bezpośredniemu wywołaniu
System.gc()
, aby wyświetlić monit czyszczenia pamięci. Powinien to być
w przypadku ART, zwłaszcza jeśli wywołujesz czyszczenie pamięci.
aby zapobiec konwersjom typu GC_FOR_ALLOC
wystąpieniami lub
ograniczeniu fragmentacji. Możesz sprawdzić, które środowisko wykonawcze jest używane
dzwoniąc pod numer System.getProperty("java.vm.version")
. Jeśli używana jest reklama ART, wartość właściwości
wynosi "2.0.0"
lub więcej.
ART używa kolektora równoczesnego kopiowania (CC), który jednocześnie kompresuje stertę Java. Z tego powodu nie należy stosować metod które są niezgodne z kompresowaniem GC (np. przez zapisywanie wskaźników do obiektów danych instancji). Jest to szczególnie ważne w przypadku aplikacji, które korzystają z Java Native Interface (JNI). Więcej informacji znajdziesz w artykule na temat zapobiegania problemom z JNI.
Zapobieganie problemom JNI
JNI w ART jest nieco bardziej restrykcyjne niż Dalvik. Szczególnie dobrym pomysłem jest do wykrywania typowych problemów w trybie CheckJNI. Jeśli Twoja aplikacja używa języka C/C++ zapoznaj się z tym artykułem:
Debugowanie Android JNI z CheckJNI
Sprawdzam kod JNI pod kątem problemów z odśmiecaniem pamięci
Kolektor równoczesny kopiowania (CC) może przenosić obiekty w pamięci w celu kompresowania. Jeśli używasz kodu w języku C/C++, nie dodawaj wykonywać operacje niezgodne z kompresowaniem GC. Ulepszyliśmy Sprawdź JNI, aby zidentyfikować potencjalne problemy (zgodnie z opisem w JNI) Lokalne zmiany plików referencyjnych w ICS).
Zwróć szczególną uwagę na
Get...ArrayElements()
i Release...ArrayElements()
funkcji. W środowiskach wykonawczych z niekompaktowym czyszczeniem pamięci
Funkcje Get...ArrayElements()
zwykle zwracają odwołanie do funkcji
w pamięci podręcznej obiektu tablicy. Jeśli zmienisz którąś z tych opcji
zwróconych elementów tablicy, obiekt tablicy został zmieniony (a argumenty
do Release...ArrayElements()
są zwykle ignorowane). Jeśli jednak
Używasz kompresowania GC, funkcje Get...ArrayElements()
mogą
spowoduje zwrócenie kopii wspomnienia. Jeśli użyjesz odwołania niewłaściwie podczas kompresowania zawartości GC,
może to spowodować uszkodzenie pamięci lub inne problemy. Na przykład:
- Jeśli wprowadzisz zmiany w zwróconych elementach tablicy, musisz wywołać metodę
Gdy skończysz, odpowiednią funkcję
Release...ArrayElements()
, aby mieć pewność, że zmiany zostaną prawidłowo skopiowane obiektu tablicy. - Przy zwalnianiu elementów tablicy pamięci musisz użyć odpowiedniej
w zależności od wprowadzonych zmian:
- Jeśli nie zostały wprowadzone żadne zmiany w elementach tablicy, użyj funkcji
tryb
JNI_ABORT
, który zwalnia pamięć bez kopiowania. zmienia się z powrotem na bazowy obiekt tablicy. - Jeśli wprowadzono zmiany w tablicy i nie potrzebujesz odwołania
użyj kodu
0
(który aktualizuje obiekt tablicy i zwalnia kopii wspomnienia). - Jeśli wprowadzono zmiany w tablicy, które chcesz zatwierdzić, i chcesz
aby zachować kopię tablicy, należy użyć funkcji
JNI_COMMIT
(która aktualizuje bazowego obiektu tablicy i zachowuje kopię).
- Jeśli nie zostały wprowadzone żadne zmiany w elementach tablicy, użyj funkcji
tryb
- Gdy zadzwonisz do:
Release...ArrayElements()
, zwróć wskaźnik, który został pierwotnie zwrócony przez użytkownikaGet...ArrayElements()
. Dla: na przykład zwiększenie wartości oryginalnego wskaźnika nie jest bezpieczne (aby przeskanować zwróconych elementów tablicy), a następnie przekazać rosnący wskaźnik doRelease...ArrayElements()
Przekazanie tego zmodyfikowanego wskaźnika może spowodować niewłaściwą pamięć do zwolnienia, co skutkuje jej uszkodzeniem.
Obsługa błędów
JNI ART zamieszcza błędy w wielu przypadkach, a Dalvik ich nie popełnia. (Raz możesz wykryć wiele takich przypadków, testując je za pomocą CheckJNI).
Jeśli na przykład funkcja RegisterNatives
jest wywoływana za pomocą metody, która
nie istnieje (prawdopodobnie dlatego, że metoda została usunięta przez narzędzie,
ProGuard), ART teraz prawidłowo przesyła NoSuchMethodError
:
08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main 08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError: no static or non-static method "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I" 08-12 17:09:41.082 13823 13823 E AndroidRuntime: at java.lang.Runtime.nativeLoad(Native Method) 08-12 17:09:41.082 13823 13823 E AndroidRuntime: at java.lang.Runtime.doLoad(Runtime.java:421) 08-12 17:09:41.082 13823 13823 E AndroidRuntime: at java.lang.Runtime.loadLibrary(Runtime.java:362) 08-12 17:09:41.082 13823 13823 E AndroidRuntime: at java.lang.System.loadLibrary(System.java:526)
ART również rejestruje błąd (widoczny w logcat), jeśli RegisterNatives
nie można wywołać żadnej metody:
W/art ( 1234): JNI RegisterNativeMethods: attempt to register 0 native methods for <classname>
Ponadto funkcje JNI GetFieldID()
i
GetStaticFieldID()
teraz poprawnie przesyła NoSuchFieldError
zamiast zwracania wartości null. Podobnie GetMethodID()
oraz
GetStaticMethodID()
teraz poprawnie zgłasza NoSuchMethodError
.
Może to prowadzić do błędów CheckJNI z powodu nieobsługiwanych wyjątków lub
wysyłane do elementów wywołujących kod natywny w Javie wyjątki. Dzięki temu
szczególnie ważne przy testowaniu aplikacji zgodnych z ART w trybie CheckJNI.
ART wymaga od użytkowników metod CallNonvirtual...Method()
JNI
(np. CallNonvirtualVoidMethod()
), aby użyć deklaracji metody
class, a nie podklasy, zgodnie z wymaganiami specyfikacji JNI.
Zapobieganie problemom z rozmiarem stosu
Dalvik miał oddzielne stosy dla kodu natywnego i Javy z domyślną przeglądarką
rozmiar stosu 32 KB i domyślny rozmiar stosu natywnego wynoszący 1 MB. ART tworzy ujednolicone
na podstawie lokalizacji. Zwykle stos ART Thread
powinien być mniej więcej taki sam jak w przypadku Dalvik. Jeśli jednak wyraźnie
ustalasz rozmiary stosu, być może trzeba będzie sprawdzić te wartości w przypadku aplikacji działających
ART.
- W języku Java przejrzyj wywołania konstruktora
Thread
, które określają jawny stos rozmiaru. Musisz na przykład zwiększyć rozmiar, jeśli wystąpiStackOverflowError
. - W C/C++ przejrzyj użycie pakietów
pthread_attr_setstack()
ipthread_attr_setstacksize()
w przypadku wątków, w których uruchamiany jest również kod w języku Java JNI Oto przykład błędu rejestrowanego, gdy aplikacja próbuje wywołać JNIAttachCurrentThread()
, gdy rozmiar pthread jest zbyt mały:F/art: art/runtime/thread.cc:435] Attempt to attach a thread with a too-small stack (16384 bytes)
Zmiany modelu obiektu
Dalvik nieprawidłowo zezwolił podklasom na zastępowanie metod prywatnych pakietów. ART przesyła ostrzeżenie w takich przypadkach:
Before Android 4.1, method void com.foo.Bar.quux() would have incorrectly overridden the package-private method in com.quux.Quux
Jeśli chcesz zastąpić metodę klasy w innym pakiecie, zadeklaruj parametr
jako public
lub protected
.
Object
ma teraz pola prywatne. Aplikacje, które refleksują nad polami
w ich hierarchiach klas, należy uważać, aby nie brać pod uwagę
Object
. Jeśli na przykład powtarzasz klasę,
jako część platformy serializacji, zatrzymaj, gdy
Class.getSuperclass() == java.lang.Object.class
zamiast kontynuować, dopóki metoda nie zwróci wartości null
.
Serwer proxy InvocationHandler.invoke()
otrzymuje teraz null
, jeśli nie ma żadnych
zamiast pustej tablicy. To zachowanie było wcześniej udokumentowane, ale
nie jest prawidłowo obsługiwany w Dalvik. Poprzednie wersje Mockito mają problemy z
dlatego podczas testowania w ART używaj zaktualizowanej wersji Mockito.
Rozwiązywanie problemów z kompilacją AOT
Kompilacja oprogramowania Ahead-Of-Time (AOT) firmy ART powinna działać w przypadku wszystkich standardowych plików Java.
w kodzie. Kompilację wykonuje aplikacja ART
narzędzie dex2oat
; w przypadku problemów związanych z
dex2oat
podczas instalacji poinformuj nas o tym (patrz Zgłaszanie problemów), abyśmy mogli jak najszybciej je rozwiązać.
jak to tylko możliwe. Pamiętaj o kilku kwestiach:
- Podczas instalacji ART przeprowadza bardziej szczegółową weryfikację przy użyciu kodu bajtowego niż Dalvik. Kod wygenerowany przez narzędzia do kompilacji na Androida powinien być prawidłowy. Jednak niektóre za pomocą narzędzi do obróbki kodu (zwłaszcza narzędzi do zaciemniania kodu), nieprawidłowe pliki są tolerowane przez Dalvik, ale odrzucone przez ART. Byliśmy we współpracy z dostawcami narzędzi, aby wykryć i rozwiązać tego typu problemy. W wielu przypadkach uzyskanie najnowsze wersje narzędzi i ponowne wygenerowanie plików DEX mogą rozwiązać te problemy. .
- Typowe problemy, które weryfikator ART powiadamia:
- nieprawidłowy przepływ kontroli
- niezbilansowane
monitorenter
/monitorexit
- Rozmiar listy typów parametrów o długości 0
- Niektóre aplikacje zależą od zainstalowanego pliku
.odex
format w formacie/system/framework
,/data/dalvik-cache
lub w zoptymalizowanym katalogu wyjściowym aplikacjiDexClassLoader
. Te są teraz plikami ELF, a nie rozszerzoną formą plików DEX. Gdy ART próbuje aby były zgodne z zasadami nazewnictwa i blokowania co Dalvik, aplikacje nie powinny formatu pliku, format może ulec zmianie bez powiadomienia.Uwaga: na Androidzie 8.0 (poziom interfejsu API 26) i , jest to
DexClassLoader
zoptymalizowany katalog wyjściowy została wycofana. Więcej informacji znajdziesz w dokumentacjiDexClassLoader()
za pomocą konstruktora.
Problemy z raportowaniem
Jeśli napotkasz problemy, które nie są spowodowane problemami z JNI dotyczącymi aplikacji, zgłoś
można je przesłać za pomocą narzędzia Android Open Source Project Issue Tracker na stronie https://code.google.com/p/android/issues/list.
Umieść w Google link "adb bugreport"
i link do aplikacji
Sklepu Play, jeśli jest dostępny. Jeśli to możliwe, załącz plik APK, który umożliwia odtwarzanie
i rozpoznają problem. Pamiętaj, że problemy (w tym załączniki) są widoczne publicznie
widoczne.