Dans cet article, nous parlerons du runtime Android. En particulier, je vais essayer de décrire brièvement mais succinctement en quoi ART et Dalvik diffèrent, et comment les outils de développement Android se sont améliorés au fil du temps. Le sujet n'est clairement pas nouveau, mais j'espère qu'il sera utile à ceux qui commencent tout juste à s'y plonger. Qui s'en soucie - bienvenue au chat.
Machine virtuelle
Voyons d'abord en quoi la JVM diffère du DVM.
La machine virtuelle Java est une machine virtuelle capable d'exécuter le bytecode Java quelle que soit la plate-forme sous-jacente. Il est basé sur le principe «Ecrire une fois, exécuter n'importe où». Le bytecode Java peut être exécuté sur n'importe quelle machine capable de prendre en charge la JVM.
Le compilateur Java convertit les fichiers .java en fichiers de classe (bytecode). Le bytecode est passé à la JVM, qui le compile en code machine pour une exécution directement sur le CPU.
Caractéristiques JVM:
- Il a une architecture de pile: une pile est utilisée comme structure de données où les méthodes sont placées et stockées. Il fonctionne en mode LIFO ou «dernier entré - premier sorti» ou «dernier entré, premier sorti».
- Ne peut exécuter que des fichiers de classe.
- Utilise un compilateur JIT.
La machine virtuelle Dalvik (DVM) est une machine virtuelle Java développée et écrite par Dan Bornstein et d'autres dans le cadre de la plate-forme mobile Android.
Nous pouvons dire que Dalvik est l'environnement pour exécuter les composants du système d'exploitation Android et les applications personnalisées. Chaque processus s'exécute dans son propre espace d'adressage isolé. Lorsqu'un utilisateur lance une application (ou que le système d'exploitation lance l'un de ses composants), le cœur de la machine virtuelle Dalvik (Zygote Dalvik VM) crée un processus distinct et protégé dans la mémoire partagée, dans lequel la VM est directement déployée en tant qu'environnement de lancement de l'application. En d'autres termes, de l'intérieur, Android ressemble à un ensemble de machines virtuelles Dalvik, chacune exécutant une application.
Caractéristiques de DVM:
- Utilise une architecture basée sur les registres: la structure de données dans laquelle les méthodes sont placées est basée sur les registres du processeur. En raison de l'absence d'opérations POP et PUSH, les instructions d'une machine virtuelle enregistrée s'exécutent plus rapidement que les instructions similaires dans une machine virtuelle empilée.
- Exécute le bytecode au format natif: Android dexer (nous en reparlerons ci-dessous) convertit les fichiers de classe au format .dex, optimisé pour une exécution sur Dalvik VM. Contrairement à un fichier de classe, un fichier dex contient plusieurs classes à la fois.
Vous pouvez en savoir plus sur l'architecture DVM ici .
Android Dexer
Les développeurs Android savent que le processus de conversion du bytecode Java en bytecode .dex pour Android Runtime est une étape clé dans la création d'un APK. Le compilateur dex fonctionne principalement sous le capot dans le développement d'applications au jour le jour, mais il affecte directement le temps de construction de l'application, la taille du fichier .dex et les performances d'exécution.
Comme déjà mentionné, le fichier dex lui-même contient plusieurs classes à la fois. Les lignes dupliquées et autres constantes utilisées dans plusieurs fichiers de classe sont incluses uniquement pour économiser de l'espace. Le bytecode Java est également converti en un autre jeu d'instructions utilisé par DVM. Le fichier dex non compressé est généralement de quelques pour cent plus petit que l'archive Java compressée (JAR) obtenue à partir des mêmes fichiers .class.
Initialement, les fichiers de classe étaient convertis en fichiers dex à l'aide du compilateur DX intégré. Mais à partir d' Android Studio 3.1 , D8 est devenu le compilateur par défaut . Par rapport au compilateur DX, D8 compile plus rapidement et génère des fichiers dex plus petits, tout en offrant de meilleures performances d'application au moment de l'exécution. Le bytecode dex obtenu de cette manière est minifié à l'aide de l'utilitaire open source ProGuard . En conséquence, nous obtenons le même fichier dex, mais plus petit. Ce fichier dex est ensuite utilisé pour créer l'apk et enfin le déployer sur un appareil Android.
Mais derrière D8 en 2018 est venu R8, qui, en fait, est le même D8, uniquement avec des ajouts.
Lorsque vous travaillez avec le plugin Android Studio 3.4 et Android Gradle 3.4.0 ou supérieur, Proguard n'est plus utilisé pour optimiser le code au moment de la compilation. Au lieu de cela, le plugin fonctionne par défaut avec R8, qui réduit le code, l'optimisation et l'obfuscation lui-même. Bien que R8 n'offre qu'un sous-ensemble des fonctionnalités fournies par Proguard, il vous permet de convertir une fois le bytecode Java en dex bytecode, ce qui réduit encore le temps de construction.
Réduction R8 et code
En règle générale, les applications utilisent des bibliothèques tierces telles que Jetpack, Gson, Google Play Services. Lorsque nous utilisons l'une de ces bibliothèques, l'application n'utilise souvent qu'une petite partie de chaque bibliothèque individuelle. Sans réduction du code, tout le code de la bibliothèque est stocké dans votre application.
Il arrive que les développeurs utilisent du code détaillé pour améliorer la lisibilité et la maintenabilité d'une application. Par exemple, des noms de variables significatifs et un modèle de conception peuvent être utilisés pour aider les autres à comprendre le code plus facilement. Mais les modèles ont tendance à générer plus de code que nécessaire.
C'est là que la R8 vient à la rescousse. Il vous permet de réduire considérablement la taille de l'application, en optimisant même la taille du code qui est réellement utilisé par l'application.
À titre d'exemple, vous trouverez ci-dessous les chiffres du rapport Shrinking Your App with R8 , présenté lors de l'Android Dev Summit '19:
Et voici à quoi ressemblait la comparaison de l'efficacité de R8 au stade de la version bêta (tirée de la source Android Developers Blog ):
Plus de détails peuvent être trouvés dans la documentation de bureau et le rapport .
ART vs DVM sous Android
DVM a été conçu spécifiquement pour les appareils mobiles et a été utilisé comme une
machine virtuelle pour exécuter des applications Android jusqu'à Android 4.4 Kitkat.
À partir de cette version, ART a été introduit en tant que runtime, et dans Android 5.0 (Lollipop) ART a complètement remplacé Dalvik.
La principale différence claire entre ART et DVM est que ART utilise la compilation AOT et DVM utilise la compilation JIT. Il n'y a pas si longtemps, ART a commencé à utiliser un hybride d'AOT et de JIT. Regardons cela de plus près.
DVM
- Utilise la compilation JIT: à chaque démarrage de l'application,
- la partie du code nécessaire pour exécuter l'application est compilée. Le reste du code est compilé dynamiquement. Cela ralentit le lancement et le fonctionnement des applications, mais réduit le temps d'installation.
- , .
- , DVM, , , ART.
- , CPU.
- Dalvik “” 4.4.
ART
- AOT , . , .
- , .
- AOT , DVM.
- , - .
- Amélioration de la récupération de place ou de la récupération de place. Lors de l'utilisation de Dalvik, les éboueurs devaient faire 2 passes de tas, ce qui a conduit à une mauvaise UX. Dans le cas de ART, une telle situation n'existe pas: il nettoie le tas une fois pour consolider la mémoire.
Et un petit diagramme de Dalvik vs ART:
JIT + AOT en ART
L'Android Runtime (ART) depuis Android 7 inclut un compilateur JIT avec profilage de code. Le compilateur JIT complète le compilateur AOT et améliore les performances d'exécution, économise de l'espace disque et accélère les mises à jour des applications et du système.
Cela se produit de la manière suivante: au
lieu d'exécuter une compilation AOT de chaque application pendant la phase d'installation, il exécute l'application sous le contrôle d'une machine virtuelle à l'aide d'un compilateur JIT (presque le même que dans Android <5.0), mais garde une trace de laquelle les sections du code d'application sont exécutées le plus souvent. Ces informations sont ensuite utilisées pour AOT compiler ces sections de code. Cette dernière opération est effectuée uniquement lorsque le smartphone est inactif pendant sa charge.
En termes simples, maintenant deux approches complètement différentes fonctionnent ensemble, ce qui donne ses avantages:
- compilation plus efficace - lors de l'exécution d'une application en temps réel, le compilateur a la possibilité d'en apprendre beaucoup plus sur son travail que d'effectuer une analyse statique, et, par conséquent, des méthodes d'optimisation plus appropriées sont appliquées à chaque situation;
- préservation de la RAM et de la mémoire permanente - le code d'octet est plus compact que le code machine, et si vous effectuez une compilation AOT de certaines sections de l'application uniquement et ne compilez pas d'applications que l'utilisateur n'utilise pas, vous pouvez économiser de manière significative de l'espace mémoire NAND;
- augmentation spectaculaire de l'installation et de la première vitesse de démarrage après la mise à jour du système - pas de compilation AOT, pas de retard.
En savoir plus sur l'implémentation du compilateur JIT dans ART ici .
Conclusion
Dans cet article, j'ai essayé de jeter un coup d'œil aux principales différences entre Dalvik et ART, et de manière générale, comment Android a amélioré ses outils de développement au fil du temps.
ART est toujours en cours de développement et de nouvelles fonctionnalités sont ajoutées pour améliorer l'expérience des utilisateurs et des développeurs.
Si cela a été utile, faites-le moi savoir dans les commentaires.