Android---DVM以及ART对JVM进行优化

Dalvik 

Dalvik 是 Google 公司自己设计用于 Android 平台的 Java 虚拟机,Android 工程师编写的 Java 或者 Kotlin 代码最终都是在这台虚拟机中被执行的。在 Android 5.0 之前叫作 DVM,5.0 之后改为 ART(Android Runtime)。在整个 Android 操作系统中,ART 位于图中红框位置。

虚拟机必须符合 Java 虚拟机规范,也就是要通过 JCM(Java Compliance Kit)的测试并获得授权。但是 DVM/ART 并没有得到授权。DVM 大多数实现与传统的 JVM 相同

\bullet Android 最初是被设计用于手机端,对内存空间要求较高;

\bullet 起初 Dalvik 目标是只运行在 ARM 架构的 CPU 上。 

针对这几种情况,Android DVM 有了自己独有的优化措施。

Dex 文件

传统 Class 文件是由一个 Java 源码文件生成的 .class 文件。Android 是把所有 Class 文件进行合并优化,然后生成一个最终的 class.dex 文件。dex 文件去除了 class 文件中的冗余信息(比如重复字符常量),并且结构更加紧凑。因此在 dex 解析阶段,可以减少 I/O 操作,提高了类的查找速度。

实例演示

1. 创建2个 java 类 Dex1.java 和 Dex2.java

public class Dex1 {private int num = 1;public int add(int i, int j) {return i + j;}
}
public class Dex4 {private int num = 1;private int count = 0;public int add(int i) {return i + num;}
}

 2. 通过 javac 命令将它们编译为 .class 文件

javac Dex1.java
javac Dex2.java

3. 通过以下命令将 Dex1.class 和 Dex2.class 打包到一个 jar 文件中

jar cvf AllDex.jar Dex1.class Dex2.class

4. 使用 dx 命令将 AllDex.jar 进行优化,并生成 AllDex.dex 文件

dx --dex --output allDex.dex AllDex.jar

注意: dx 命令需要配置环境变量中。

5. 通过 Android SDK 中的工具 dexdump 查看其字节码

dexdump -d -l plain AllDex.dex

结果如下

架构基于寄存器&基于堆栈结构

JVM 指令集是基于栈结构来执行的,Android 是基于寄存器的是在内存中模拟一组寄存器。Android 的字节码(smali)更多的是二地址指令和三地址指令。

DVM 字节码和 JVM 字节码的区别,如下代码示例:

public int add(int i, int j){return i +j;
}

1. 编译为 Dex1.class 文件后,add 方法的字节码如下,通过4行指令完成

2. 通过 dx 命令将 Dex1.class 优化为 .dex 文件后,再次查看它的 Dalvik 字节码。

add-int 指令需要3个寄存器参数:v0、v1、v2,这个指令会将 v2 和 v3 进行相加运算,然后将结果保存在寄存器 v0 中。return 指令将结果返回。

Dalvik 通过2行指令完成。基于寄存器的指令比基于栈的指令少,但基于寄存器的指令更长。二者比较如下:

内存管理与回收

DVM 和 JVM 另一个显著的不同就是内存结构的区别,主要体现在对堆内存的管理。Dalvik 虚拟机中将堆内存划分为两部分:Active HeanpZygote Heap。如下图所示

 图中的 Card Table 和 两个 Heap Bitmap 主要用来记录垃圾收集过程中对象的引用情况。

为什么要分 Zygote 和 Active 两部分?

Android 系统中的第一个 Dalvik 虚拟机是由 Zygote 进程创建的,而应用程序进程是由 Zygote 进程 fork 出来的。Zygote 进程是在系统启动时创建的,它会完成虚拟机的初始化、库的加载、预置类库的加载和初始化等操作。

在系统需要一个新的虚拟机实例时,Zygote 通过复制自身最快速的提供一个进程。另外对于一些只读的系统库,所有的虚拟机实例都与 Zygote 共享一块内存区域,大大减少了内存开销。如下图所示

当启动一个应用时,Android 的操作系统需要为应用程序创建新的进程,而这一操作是通过一种写实拷贝技术直接复制 Zygote 进程而来。这就意味着在开始的时候,应用程序进程和 Zygote 进程共享了同一个用来分配内存的堆。然而,当 Zygote 进程或者应用程序进程对该堆进行写操作时,内存就会进行真正的拷贝操作,使得 Zygote 进程和应用程序进程分别拥有自己的一份拷贝。拷贝是一件费时费力的事情,因此为了尽量避免拷贝,Dalvik 虚拟机将自己的堆划分为了两部分

Zygote 进程在启动过程中创建 Dalvik 虚拟机时,只有一个堆。但是当 Zygote 进程在 fork 第一个应用程序进程之前,会将已经使用的那部分堆内存划分为一部分,把还没有使用的堆内存划分为另外一部分。前者就称为 Zygote 堆,后者就称为 Active 堆。无论是 Zygote 进程,还是应用程序进程,当它们需要分配对象的时候,都在 Active 堆上进行。这样就可以使得 Zygote 堆尽可能少的被执行写操作,可以减少执行写时拷贝的操作时间。

Dalvik 虚拟机堆

在 Dalvik 虚拟机中,堆实际上就是一块匿名共享内存。Dalvik 虚拟机并不是直接管理这块匿名共享内存,而是将它封装成一个 mspace,交给 C 库来管理。

为什么这么做呢?

因为内存碎片问题是一个通用问题,不只是 Dalvik 虚拟机、 Java 堆为对象分配内存时会遇到,在 C 库的 malloc 函数在分配内存时也会遇到。

Android 系统使用的 C 库 bionic,使用了 Doug Lea 写的 dlmalloc 内存分配器。调用函数 malloc 的时候,使用的是 dlmalloc 内存分配来分配内存。这是一个成熟的内存分配器,可以很好的解决内存碎片问题。因此,Dalvik 虚拟机就很机制的利用 C 库里面的dlmalloc 分配器来解决内存碎片问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/106473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UGUI交互组件ScrollBar

一.ScrollBar的结构 对象说明Scrollbar挂有Image和Scrollbar组件的主体对象Sliding Area表示滑动范围Handle滑块 二.Scrollbar的属性 属性说明Handle Rect控制柄对象的引用Direction拖动控制柄时滚动条值增加的方向Value滚动条的当前值,范围为 0.0 到 1.0Suze控制柄…

Hadoop3教程(四):HDFS的读写流程及节点距离计算

文章目录 (55)HDFS 写数据流程(56) 节点距离计算(57)机架感知(副本存储节点选择)(58)HDFS 读数据流程参考文献 (55)HDFS 写数据流程 …

软件测试学习(四)自动测试和测试工具、缺陷轰炸、外包测试、计划测试工作、编写和跟踪测试用例

目录 自动测试和测试工具 工具和自动化的好处 测试工具 查看器和监视器 驱动程序 桩 压力和负载工具 干扰注入器和噪声发生器 分析工具 软件测试自动化 宏录制和回放 可编程的宏 完全可编程的自动测试工具 随机测试:猴子和大猩猩 使用测试工具和自动…

Shell命令笔记2

大家好,分享下最近工作中用得比较多的shell命令,希望对大家有帮助。 获取数组长度: ${#array_name[*]}获取脚本相对路径 script_path$(dirname "$0")获取脚本的名字 script_name$(basename "$0")获取脚本的绝对路径 …

如何从 Pod 内访问 Kubernetes 集群的 API

Kubernetes API 是您检查和管理集群操作的途径。您可以使用Kubectl CLI、工具(例如curl)或流行编程语言的官方集成库来使用 API 。 该 API 也可供集群内的应用程序使用。Kubernetes Pod 会自动获得对 API 的访问权限,并且可以使用提供的服务帐户进行身份验证。您可以通过使…

论文阅读:Image-to-Lidar Self-Supervised Distillation for Autonomous Driving Data

目录 摘要 Motivation 整体架构流程 技术细节 雷达和图像数据的同步 小结 论文地址: [2203.16258] Image-to-Lidar Self-Supervised Distillation for Autonomous Driving Data (arxiv.org) 论文代码:GitHub - valeoai/SLidR: Official PyTorch implementati…

深度学习—cv动物/植物数据集

文章目录 动物相关植物相关 动物相关 Edinburgh Pig Behavior Video Dataset:https://homepages.inf.ed.ac.uk/rbf/PIGDATA/ WLD 动物目标检测数据集: https://github.com/hellock/WLD 猪脸识别:https://blog.51cto.com/u_15404184/5289690 AFD动物面部数据集&…

【随笔】论多线程CPU离线渲染器的实现:A CPU BASED OFFLINE RENDERING ENGINE

前言 小熊挺喜欢玩游戏的,对于游戏画面有所追求,记得高中第一次玩战地的时候,惊叹于画面细腻的表现,并且还能开坦克车,这样的事情深深吸引了我。我是一个画面党,为了追求更好的画质表现我开始研究设置面板…

【Linux常用命令10】用户管理和文件权限命令

useradd:用于创建新的用户 useradd [选项] 用户名 参数 含义 -D 改变新建用户的预设值 -c 添加备注文字 -d 新用户每次登陆时所使用的家目录 -e 用户终止日期,日期的格式为YYYY-MM-DD -f 用户过期几日后永久停权。当值为0时用户立即被停权&a…

sql 注入(2), 文件读写 木马植入 远程控制

sql 注入 文件读写 木马植入 远程控制 一, 检测读写权限 查看mysql全局变量 SHOW GLOBAL VARIABLES LIKE %secure%secure_file_priv 空, 则任意读写secure_file_priv 路径, 则只能读写该路径下的文件secure_file_priv NULL, 则禁止读写二, 读取文件, 使用 load_file() 函数…

mysql误删误操作恢复数据,比传统方式和binlog2sql更快速用的恢复方式-reverse_sql恢复数据(单表多表)

场景: 误操作删除了某个表的数据,本文只讲工具的使用,首先自己通过mysqlbinlog或者记录找到误操作的时间范围:开始时间和结束时间,已经确定好是哪个binlog了下面以误删为例。 查看binlog是否开启 show variables like …

SpringBoot面试题2:SpringBoot与SpringCloud 区别?SpringBoot和Spring、SpringMVC的区别

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot与SpringCloud 区别? Spring Boot 和 Spring Cloud 是 Spring 生态系统中的两个关键组件,它们有以下区别: 定位:Spring Boot 用于简…

Node.js中Buffer API详解

Node.js中Buffer API详解 在Node.js中,Buffer是一个用于处理二进制数据流的全局对象,它类似于数组,但可以存储任意大小的数据。Buffer对象是由C代码实现的底层结构,而JavaScript代码则提供了一些高级的API。本文将介绍Node.js中B…

数据结构:队列

特点 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为 队尾( Tail/Rear ) 出队列:进行删除操作的一端称…

c#设计模式-行为型模式 之 备忘录模式

🚀简介 备忘录模式(Memento Pattern)是一种行为型设计模式,它保存一个对象的某个状态,以便在适当的时候恢复对象。所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象…

一致性公式证明

首先,假设存在两个不同的聚类假设 f 1 f^1 f1和 f 2 f^2 f2,它们在两个视角上的聚类结果分别为 y 1 ∈ { − 1 , 1 } n y^1\in\{-1,1\}^n y1∈{−1,1}n和 y 2 ∈ { − 1 , 1 } n y^2\in\{-1,1\}^n y2∈{−1,1}n。 证明一致性不等式: ​ …

Matlab-ODE45:求解状态变量(微分方程组)

ode45函数 ode45实际上是数值分析中数值求解微分方程组的一种方法,4阶五级Runge-Kutta算法。 调用方法 ​ 其实这种方程的每一个状态变量都是t 的函数,我们可以从现代控制理论的状态空间来想。因此返回[ t , x ],其中t是一个列向量&#xf…

Hadoop3教程(十一):MapReduce的详细工作流程

文章目录 (94)MR工作流程Map阶段Reduce阶段 参考文献 (94)MR工作流程 本小节将展示一下整个MapReduce的全工作流程。 Map阶段 首先是Map阶段: 首先,我们有一个待处理文本文件的集合; 客户端…

机器学习——奇异值分解二(特征分解+SVD纯理解)

矩阵的特征分解 特征值和特征向量的定义 抄来的:奇异值分解 困惑1:特征值和特征向量,和原矩阵是怎样的关系,需要一个栗子进行更具象的认识 困惑2:为什么多个特征向量组合成的矩阵,可以构成矩阵A的特征分解…

自动驾驶中的数据安全和隐私

自动驾驶技术的发展已经改变了我们的出行方式,但伴随着这项技术的普及,数据安全和隐私问题也变得愈发重要。本文将探讨自动驾驶中的数据收集、数据隐私和安全挑战,以及如何保护自动驾驶系统的数据。 自动驾驶中的数据收集 在自动驾驶技术中…