Android çalışma zamanı (ART), Android çalıştıran cihazlar için varsayılan çalışma zamanıdır 5.0 (API düzeyi 21) ve sonraki sürümler. Bu çalışma zamanı bir dizi özellik sunar. . ART'ın yeni özellikleri hakkında daha fazla bilgiyi ART.
Ancak Dalvik'te işe yarayan bazı teknikler ART'ta işe yaramaz. Bu doküman, mevcut bir dosyayı taşırken dikkat etmeniz gereken şeyler hakkında sizi uygulamasını ART ile uyumlu hale getirin. Çoğu uygulama ART.
Atık toplama (GC) sorunlarını ele alma
Dalvik altında, uygulamalar çoğu zaman açıkça telefon etmeyi faydalı bulur
Atık toplama (GC) istemi için System.gc()
. Bu özellik,
özellikle atık toplama işlemi yapıyorsanız ART ile çok daha az
GC_FOR_ALLOC
türünü önlemek için
kullanılması anlamına gelir. Hangi çalışma zamanının kullanılmakta olduğunu doğrulayabilirsiniz
System.getProperty("java.vm.version")
numaralı telefonu arayarak. ART kullanılıyorsa mülkün değeri
"2.0.0"
veya daha yüksek.
ART, Java yığınını eşzamanlı olarak sıkıştıran Eşzamanlı Kopyalama (CC) toplayıcısını kullanır. Bu nedenle, tekniklerin kullanımı sıkıştırmak için GC ile uyumlu olmayan (imleçleri nesneye kaydetme gibi) örnek verileri) görebilirsiniz. Bu, özellikle Java Native Interface (JNI). Daha fazla bilgi için JNI Sorunlarını Önleme bölümüne bakın.
JNI sorunlarını önleme
ART'ın JNI'si, Dalvik'inkinden biraz daha katı. Bu, özellikle de sık karşılaşılan sorunları yakalamak için CheckJNI modunu kullanmanızı öneririz. Uygulamanız C/C++ kullanıyorsa aşağıdaki makaleyi incelemelisiniz:
Hata ayıklama CheckJNI ile Android JNI
Atık toplama sorunları için JNI kodunu kontrol etme
Eşzamanlı Kopyalama (CC) toplayıcısı, sıkıştırma için bellekteki nesneleri taşıyabilir. C/C++ kodu kullanıyorsanız GC'yi sıkıştırmayla uyumlu olmayan işlemler gerçekleştirme. Gelişmiş Bazı olası sorunları tanımlamak için CheckJNI'yı kontrol edin (JNI'da açıklandığı gibi) ICS'deki Yerel Referans Değişiklikleri).
Özellikle dikkat edilmesi gereken bir alan,
Get...ArrayElements()
Release...ArrayElements()
işlevlerine dahildir. Kompakt olmayan GC ile çalışma zamanlarında,
Get...ArrayElements()
işlevleri genellikle
dizi nesnesini destekleyen gerçek bellekte yer alır. Anahtar kelimelerinizden birinde
dizi öğeleri döndürüldüğünde, dizi nesnesinin kendisi değiştirilmiş (ve bağımsız değişkenlerin
Release...ArrayElements()
ifadeleri genellikle yoksayılır). Ancak,
sıkıştırma GC kullanımdaysa Get...ArrayElements()
işlevleri
belleğin bir kopyasını alabilirsiniz. GC'yi sıkıştırırken referansı kötüye kullanırsanız
kullanılması bellek bozulmasına veya başka sorunlara yol açabilir. Örnek:
- Döndürülen dizi öğelerinde herhangi bir değişiklik yaparsanız
uygun
Release...ArrayElements()
işlevini kullanın, yaptığınız değişikliklerin temel alınan reklama doğru kopyalandığından dizi nesnesini anlatacağım. - Bellek dizisi öğelerini serbest bıraktığınızda,
modunu seçin:
- Dizi öğelerinde herhangi bir değişiklik yapmadıysanız
JNI_ABORT
modu, kopyalamadan belleği serbest bırakır temel dizi nesnesine dönüşür. - Dizide değişiklik yaptıysanız ve herhangi bir referansa ihtiyacınız yoksa
için dizi nesnesini güncelleyen ve serbest bırakan
0
kodunu kullanın. anının kopyası) ekleyebilirsiniz. - Kaydetmek istediğiniz dizide değişiklikler yaptıysanız ve
dizinin kopyasını saklamak için
JNI_COMMIT
(güncellenen) alt dizi nesnesini oluşturur ve kopyayı saklar).
- Dizi öğelerinde herhangi bir değişiklik yapmadıysanız
Release...ArrayElements()
adlı kişiyi aradığınızda aynı şekilde geri dönün ilk olarakGet...ArrayElements()
tarafından döndürülen işaretçi. Örneğin, Örneğin, orijinal işaretçiyi artırmak güvenli değildir (örneğin, dizi öğeleri döndürüldüğünden emin olun) ardından artırılmış işaretçiyiRelease...ArrayElements()
Bu değiştirilmiş işaretçiyi aktarmak, bellekte bozulmaya yol açabilir.
Hata işleme
ART'ın JNI hizmeti, Dalvik'in göndermediği birçok durumda hata bildirmektedir. (Bir kez Bu tür durumların çoğunu CheckJNI ile test ederek yakalayabilirsiniz.)
Örneğin, RegisterNatives
mevcut değildir (belki de yöntemin
ProGuard), ART artık NoSuchMethodError
öğesini düzgün şekilde fırlatıyor:
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)
RegisterNatives
, şu durumda bir hata da kaydeder (logcat'te görünür)
yöntem olmadan çağrıldı:
W/art ( 1234): JNI RegisterNativeMethods: attempt to register 0 native methods for <classname>
Buna ek olarak JNI, GetFieldID()
ve
GetStaticFieldID()
artık düzgün bir şekilde NoSuchFieldError
atıyor
değerini döndürür. Benzer şekilde, GetMethodID()
ve
GetStaticMethodID()
artık düzgün bir şekilde NoSuchMethodError
atıyor.
Bu durum, işlenmeyen istisnalar veya
yerel kodun Java çağrıcılarına atılan istisnalar. Bu da,
ART ile uyumlu uygulamaların CheckJNI moduyla test edilmesi özellikle önemlidir.
ART, JNI CallNonvirtual...Method()
yöntemlerini kullanmasını bekler
(ör. CallNonvirtualVoidMethod()
)
sınıfını kullanır.
Yığın boyutu sorunlarını önleme
Dalvik, varsayılan Java ile yerel ve Java kodu için ayrı yığınlara sahipti
grup boyutu 32 KB ve varsayılan yerel grup boyutu 1 MB'tır. ART,
daha iyi bir yerleşim yeri
kullanabilirsiniz. Normalde, ART Thread
grubu
yaklaşık olarak Dalvik ile aynı olmalıdır. Ancak, açık bir şekilde
veya başka bir yerde çalışan uygulamalar için bu değerleri
ART.
- Java'da, açık bir yığın belirten
Thread
oluşturucuya yapılan çağrıları inceleyin seçin. Örneğin,StackOverflowError
gerçekleşirse boyutu artırmanız gerekir. - C/C++'ta,
pthread_attr_setstack()
ve Java kodu da çalıştıran iş parçacıkları içinpthread_attr_setstacksize()
JNI Bir uygulama JNI'yi çağırmaya çalıştığında günlüğe kaydedilen hatanın örneğini burada bulabilirsiniz pthread boyutu çok küçük olduğundaAttachCurrentThread()
:F/art: art/runtime/thread.cc:435] Attempt to attach a thread with a too-small stack (16384 bytes)
Nesne modeli değişiklikleri
Dalvik, alt sınıfların gizli paket yöntemlerini geçersiz kılmasına yanlışlıkla izin verdi. ART, aşağıdaki durumlarda uyarı gönderir:
Before Android 4.1, method void com.foo.Bar.quux() would have incorrectly overridden the package-private method in com.quux.Quux
Bir sınıfın yöntemini farklı bir pakette geçersiz kılmak istiyorsanız
yöntemini public
veya protected
olarak ayarlayın.
Object
artık özel alanlara sahip. Alanları yansıtan uygulamalar
kendi sınıf hiyerarşilerinde,
Object
alanları. Örneğin, bir sınıfı geliştiriyorsanız
bir serileştirme çerçevesinin parçası olarak hiyerarşik
Class.getSuperclass() == java.lang.Object.class
yerine null
değerini döndürür.
InvocationHandler.invoke()
proxy'sinull
bağımsız değişkenlerini kullanır. Bu davranış daha önce belgelenmiş olsa da
içeren bir e-posta alırsınız. Mockito'nun önceki sürümlerinde
Bu nedenle, ART ile test yaparken güncellenmiş bir Mockito sürümünü kullanın.
AOT derleme sorunlarını düzeltme
ART'ın Ahead-Of-Time (AOT) Java derlemesi, tüm standart Java uygulamaları için çalışır
girin. Derleme, ART tarafından gerçekleştirilir
dex2oat
aracı;
dex2oat
, yükleme sırasında bize bildirin (Raporlama Sorunları'na bakın). Böylece, sorunları en kısa sürede çözebiliriz.
yardımcı olabilirsiniz. Göz önünde bulundurulması gereken birkaç sorun:
- ART, yükleme sırasında Dalvik'inkinden daha sıkı bayt kodu doğrulaması yapar. Android derleme araçları tarafından oluşturulan kod sorunsuz olmalıdır. Ancak bazı işleme sonrası araçları (özellikle kod karartma işlemi yapan araçlar) Dalvik tarafından tolere edilen ancak ART tarafından reddedilen geçersiz dosyalar. Bir süredir araç tedarikçileriyle birlikte çalışarak bu tür sorunları tespit edip giderebilirsiniz. Çoğu durumda, son haline getirmek ve DEX dosyalarını yeniden oluşturmak bu sorunları giderebilir. neden olabilir.
- ART doğrulayıcısı tarafından işaretlenen bazı tipik sorunlar şunlardır:
- geçersiz kontrol akışı
- dengesiz
monitorenter
/monitorexit
- 0 uzunluklu parametre türü liste boyutu
- Bazı uygulamaların yüklü
.odex
dosyasına bağımlılıkları var biçimi/system/framework
,/data/dalvik-cache
veyaDexClassLoader
optimize edilmiş çıkış dizininde. Bu dosyaları artık genişletilmiş bir DEX dosyası biçimi değil, ELF dosyalarıdır. ART, ile aynı adlandırma ve kilitleme kurallarına uymasını gerektirirse, uygulamalar dosya biçiminde olmalıdır; bildirimde bulunulmadan değiştirilebilir.Not: Android 8.0 (API düzeyi 26) ve daha yüksek,
DexClassLoader
için optimize edilmiş çıkış dizini desteği sonlandırıldı. Daha fazla bilgi içinDexClassLoader()
. kurucusu.
Raporlama sorunları
Uygulama JNI sorunlarından kaynaklanmayan bir sorunla karşılaşırsanız
https://code.google.com/p/android/issues/list adresindeki Android Açık Kaynak Proje Sorun Takip Aracı üzerinden iletebilirsiniz.
Google'a bir "adb bugreport"
ve uygulamanın bağlantısını ekleyin
Varsa Play Store. Aksi takdirde, mümkünse
düşünmesi gerekir. Sorunların (ekler dahil) herkese açık olduğunu unutmayın
görünür.