十二、android对JVM的优化

2023年 10月 16日 93.5k 0

概述

安卓的四层架构,最上面两层,(应用层,应用框架层)都是java编写的,剩余三层是 库和运行时,硬件层,linux内核层 是C++写的。安卓中我们接触最多的还是 java代码(kotlin只是java的高级变种,最终也是转化成java代码统一处理)。

所以,安卓代码实际上也是运行在JVM上,只不过 GOOGLE针对 JVM进行了专项优化,使之更加适合在移动平台上运行。

注意:在安卓5.0之前,优化之后的JVM,被谷歌叫做 DVM (dalvik Virtual Machine),5.0以及以后,都称之为 ART (android Runtime)

ART的位置,在 应用框架层再往下。处在库和运行时这一层

image.png

优化细节

由于ART是要运行在移动端,手机,平板,对于内存控制的要求就更高,毕竟手机平台的内存不可能比得上大型PC。 而且ART的前身DVM当初设计出来只是为了适配 ARM架构的CPU。
所以,针对更严格的内存要求,以及特定的ARM CPU架构,对JVM做出自己的优化措施。

Dex VS class

传统Class文件是由一个java文件通过javac命令编译而成, android则是把所有的class文件进行优化合并,然后生成一个最终的classes.dex文件,dex文件去掉了 class文件中的冗余信息,使之结构更加紧凑,所以在dex解析阶段,可以减少I/O操作,提高类查找速度。

理解:dex是合并了所有class之后的产物。回顾一下,class文件结构中,存在一个常量池,是保存了某一个class里面的常量集合,那么多个class中是否可能存在多个相同的常量呢? 很有可能,比如两个 class都定义了相同的常量字符串,那么dex将他们整理到一起,集中放在一起,再安排带缓存的读取机制,那么在访问多个类的时候便能减少IO次数了。

比如下方两个java类:

image.png

通过javac和jar命令生成一个jar包:

image.png

然后用dx命令将他们生成 dex文件:

image.png

最后通过dexdump查看dx文件的内容:

image.png

如下:

image.png

可以看到,两个类的信息,都在同一个dex中。

问题

将多个class集中到一个dex中,能达到节约空间,资源整合,减少I/O的优点,但是同样带来了一些问题,比如 经典的65535问题。当一个dex中的方法数超过65535,就会导致无法打包。

注意:很多网上的说法是,65535问题是由于 解析dex文件时使用了short来存储 方法个数,这种说法是错误的。

正确的解释应该是:

DVM的源代码中,在将多个class编排到dex中时,直接对方法数 ,成员变量数,都进行了最大数量的限制,超出数量就抛出异常。

image.png

指令基于寄存器 VS 指令基于栈

JVM的指令集的执行,是基于栈结构去执行的,而 android 是基于寄存器。区别如下:

如下一个add方法,
image.png

在 JVM中执行的指令集如下:

image.png
有4个步骤,2个变量分别入栈,对两个变量进行add操作,以及最终的return。

而 安卓执行这一个方法的 指令集为:

image.png

原来的4个步骤,浓缩成了2个。
ART是基于寄存器,add-int这个指令 会将 v2和v3相加运算,最终将结果保存在寄存器 v0中。

安卓的ART指令执行的过程,相当于原来JVM的执行过程的优势为:

  • 速度更快
  • 指令条数更少

而相应地做出了牺牲:

  • 指令更长
  • 指令更复杂
  • 可移植性更差

堆内存的管理优化

ART将堆分为了两个部分,分别是
- 共有 Zygote Heap
- 私有的 Activte Heap

所有的app进程都和zygote进程共享同一个zygoteHeap区域。

ART将堆内存分成两块的原因是:每一个安卓app进程都是由 Zygote进程fork而来。当Zygote进程在fork第一个app进程时,会将已经使用的堆内存划分为 Zygote Heap ,将没有使用的那部分内存划分为 Active Heap,当需要分配对象时,都在 ActiveHeap中进行。这样可以使得ZygoteHeap尽可能少的执行写操作。可以减少拷贝的时间。

堆 heap,其实就是一块匿名共享内存,安卓系统为了解决内存碎片的问题,将内存的分配和管理,交给了 底层C库中的malloc函数。

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论