Derinlemesine Android talimat optimizasyonu ve Java yöntemi çağrısı

Önce küçük bir deney yapın:

Apk etkinliğine bir Düğme ve Metin Görünümü yerleştirin ve sonucu TextView'da görüntülemek için Düğmeye tıklayın.

Apk kodu aşağıdaki gibidir:

publicclassMainActivityextendsAppCompatActivity {Düğme düğmesi; TextView textView; @OverrideprotectedvoidonCreate (Bundle SavedInstanceState) {super.onCreate (SavedInstanceState); setContentView (R.layout.activity_main); textView = findViewById (R.id. button); button.setOnClickListener (newView.OnClickListener () {@OverridepublicvoidonClick (View v) {Test test = newTest (); String s = test.getValue (); textView.setText (s);}});}}

Test sınıfının kodu aşağıdaki gibidir:

public class Test {

public String getValue () {

döndür bu yöntem getValued;}}

Düşünmeye çalışın, metin kutusunda görüntülenen sonuç ne olacak?

İlk sonuç:

Normal çalışıyorsa sonuçlar aşağıdaki gibi olacaktır (bu testin tamamı Android AOSP N'de yürütülür):

bu yöntem getValued

Daha fazla test

Ardından, daha fazla test edin.

Apk'nin PathClassLoader öğesinin ClassPath ön kısmına bir dex enjekte ediyoruz. Bu dex, aşağıdaki gibi önceki Testin paket adı + sınıf adı ile tutarlı olan yalnızca bir sınıf içerir:

public class Test {public String getValue () {return this is method getValue from dex;} public String abc () {return this is method abc !!!;}}

Bu, sıcak onarımın en basit prensibidir, tahmin et bu sefer sonuç nedir?

2. sonuç

Bu sefer sonuç ne olacak?

Aslında, hata ayıklama sürümünde doğru sonucu alabiliriz:

Yayın versiyonunda, sonuç hayal ettiğimiz gibi değil. Sonuç şu şekilde:

Fenomen açıklaması

Neden böyle bir fenomen var: açıkça getValue yöntemi çağrılıyor, neden abc yönteminin sonucu döndürüldü?

Bu fenomeni açıklamak için, Android sanal makine tarafından kod çalıştırma ilkelerine ilişkin belirli bir anlayışa sahip olmamız gerekir.

Java kodunu apk olarak derlediğimizde, derleyici java dosyasını bir sınıf dosyasına dönüştürmek için javac'ı kullanır ve ardından sınıf dosyasını bir dex dosyasına dönüştürmek için dx'i kullanır (eğer bu bir jackjill derleyicisiyse, sınıf oluşturma süreci olmayacaktır).

Apk kurulduğunda, PMS, apk'yi optimize etmek için installd aracılığıyla dex2oat sürecini başlatır.

Sistemi başlattığımızda, sanal makine önce BootClassLoader'ı yükler, ardından SystemClassLoader'ı yükler ve sırasıyla BOOTCLASSPATH ve SYSTEMSERVERCLASSPATH'deki ilgili jar paketlerindeki sınıfları yükler.

Apk başlatıldığında, apk ile ilgili ve bağımlı kütüphanelerdeki sınıfları belleğe yüklemek için bir PathClassLoader oluşturulacaktır.

Başlangıçta PathClassLoader'ın clssapath'ına yeni bir jar / dex enjekte edersek, PathClassLoader ilk olarak önceki jar / dex'i çalışma zamanı sırasında yükleyecek ve böylece apk'nin kendisinin değiştirilmesini geçersiz kılacaktır.

Ancak sanal makinenin mekanizmasını genellikle fark etmiyoruz.

Apk yüklenirken, apk bir hata ayıklama sürümü ise yorumlanmış bir şekilde yürütülmeye zorlanacaktır. Şu anda yürütme bayt kodudur. Gördüğümüz bayt kodu şudur:

Yani, invoke-virtual + methodID yöntemi yürütülür. Bu methodID, apk'nin kendi dex'inde saklanır ve her dex'in bir String tablosu ve bir Yöntem tablosu vardır (tabii ki Sınıf tablosu gibi başka tablolar da vardır).

String tablosu aracılığıyla, String'in belirli bir dizine neye karşılık geldiğini öğrenebilirsiniz; yöntem tablosu aracılığıyla, methodID'ye karşılık gelen StringID'yi alabilir ve ardından String tablosunda yöntem adını bulabilirsiniz.

Sanal makine, yöntemi yüklenen önbellekten bulmak için yöntem adını kullanır.Yöntem bulunamazsa, sınıf yolundan yükler ve çözer ve son olarak karşılık gelen yöntemi bulur.

Daha sonra normal hata ayıklama sürümü yorumlandığında ve yürütüldüğünde, bu süreçte herhangi bir sorun yoktur; eski sınıfın üzerine yazmak için yeni sınıf kullanıldığında, derleme sırasında belirlenen yöntem kimliği aracılığıyla doğru yöntem adı yine de elde edilebilir. Doğru yönteme gidin ve uygulayın.

Ancak yayın sürümünde dex optimize edilecek. dex2oat, sistem özelliğindeki yapılandırmaya göre optimizasyon derecesini belirler. AOSP N'de varsayılan yapılandırma aşağıdaki gibidir:

Yalnızca yorumlama modunun optimizasyonu aslında yalnızca dalvik talimat düzeyinde optimizasyondur ve makine kodu oluşturmaz (hız gibi diğer optimizasyon modları bazı makine kodları oluşturur ve her şey modu tamamen derlenir ve tüm bayt kodları şu şekilde optimize edilir: Makine kodu), ancak invoke-virtual gibi talimatları hızla optimize edecek ve bunları invoke-virtual-quick'e dönüştürecektir.

Optimizasyonun amacı, methodID aramasını vtable aramasına dönüştürmektir. MethodID küresel bir dex aramadır.Sınıfta vtable aramasıyla karşılaştırıldığında, verimlilik çok daha yüksektir.Sonuçta, bir dex'te on binlerce yöntem olabilir ve genellikle bir sınıfta yalnızca birkaç ila düzinelerce yöntem vardır.

Yalnızca yorumun optimizasyonu, derleme sırasında yalnızca sınıfın adının elde edilebileceği değil, aynı zamanda sınıfın tanımının da elde edilebileceği önermesine dayanmaktadır.

Dex'i dinamik olarak yüklediğimiz için, bu dex yalnızca sınıf yükleyici dex'i yüklediğinde keşfedilecektir. Dex2oat derlendiğinde, yalnızca apk'nin kendisinde sınıfın varlığını bilir.

Dex2oat yalnızca yorumlama optimizasyonu gerçekleştirdiğinde, derleme bağımlılığı orijinal yöntemdir ve bu da oluşturulan vtable dizininin orijinal Test sınıfındaki yöntem dizini olmasına neden olur. Ancak, çalıştırıldığında, yeni Test sınıfı bir abc yöntemi ekler.Android'deki çeşitli String tabloları, yöntem tabloları ve vtables alfabetik sıraya göre sıralanır ve bu da abc yönteminin Test yönteminden önce sıralanmasına neden olur. Orijinal vtable dizininde bulunan yöntem, abc yöntemi olur.

Vtable indeksinin değişmesi nedeniyle, Test yönteminin açıkça çağrıldığı tuhaf bir fenomen var, ancak sonuç abc yöntemidir.

Doğrulama-yok modunda derlersek (optimizasyonu hızlandırmadan veya makine kodunda derlenebilen diğer modlar olmadan) ve yorumlanmış modda çalışmasına izin verirsek, sorun olmayacaktır. Ancak, apk Manifest'te android: vmSafeMode = true olarak ayarlanmışsa, zorunlu derleme için başka modlar kullanılıp kullanılmadığına bakılmaksızın, apk her zaman salt yorumlama modunda derlenecek ve sorunun devam etmesine neden olacaktır.

Örneğin, derlemek için hızı kullanırsak, günlük hala yalnızca yorumlanır:

sonuç olarak

Apk sıcak onarım, eklenti oluşturma ve dinamik yükleme sırasında, birden çok kavanoz / dex genellikle aynı sınıfı içerir. Yükseltme ihtiyacı nedeniyle sınıf yapısı değişirse, açıklanması zor olan bazı çukurlar gizlenecektir, bu yüzden dikkatli olun.

Tercihli politikalar çok cazip, 210.000 kişi bu şehre yerleşti, ancak utanç verici bir durum buldu ...
önceki
Hongqi yeni teknoloji markası, düzen otomasyonu / istihbaratı yayınladı
Sonraki
Kamu iktisadi teşebbüslerinin reformu ve gelişmesiyle ilgili basın toplantısının dokuz altın cümlesi, onları okumalısınız!
Yazın tek Hollywood gişe rekorları kıran film mi? Kun Ling'in oynadığı "Sky Rescue", sürümde iyi bir üne sahip!
Anhui: Yangtze Nehri boyunca 60.000 ton katı atık keyfi olarak yığılıyor ve kanalizasyon Yangtze Nehri'ne akabilir!
2018 Java Advanced Interview No. 7-MySQL Alt Veritabanı Alt Tablo Prensibi
TVB, Hong Konglu kardeşleri bekarların anneleri açıkça kabul etmeyi ve "asker almayı" reddettiklerini vurgulamaya çağırıyor: Erkek çocukları ayrım gözetmeksizin eve götürmeyin
Pist için doğan Ford GT Carbon Series resmi haritası
Bu ne? Bu Yin Yang mavisi ve siyah Air Jordan 1 çifti, Lightning eklem adından bile daha sınırlıdır!
Mesleğinize saygı gösterin! TVB'nin 52 yaşındaki popüler erkek tanrısı, yeni dram için karısının övgüsünü alıyor
Johnson Controls, araba aküsü işini 14 milyar dolara satabilir
2018 BAT mülakat soruları (5) -Java bellek modeli ve iş parçacığı yürütme ilkesi
Tatlı bakışlar başkalarını kıskanıyor! Justin Bieber kız arkadaşına evlenme teklif ettikten sonra Bahamalar tatilinin fotoğrafları!
Gaz arzı, elektrik fiyatı, 5G... Bu insanların geçim kaynakları merkezi işletmelerin temsilcilerinden geliyor! İki Oturumun Yeni Sesleri
To Top