Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >笔记10 - DVM或ART是如何对JVM进行优化的

笔记10 - DVM或ART是如何对JVM进行优化的

作者头像
码农帮派
发布于 2021-01-12 06:56:57
发布于 2021-01-12 06:56:57
74100
代码可运行
举报
文章被收录于专栏:码农帮派码农帮派
运行总次数:0
代码可运行

DVM大多数实现和传统的JVM相似,但是为了满足Android在手机端内存的限制,Dalvik对JVM做了一些独有的优化。

Dex文件

传统的class文件是由Java源码文件编译生成的,而Android在编译打包的时候,会将所有的class文件整合优化,最终生成class.dex文件。dex文件中去掉了class文件中的冗余信息,使得编译打包之后的class.dex文件更加紧凑,这样在ClassLoader加载解析dex文件的时候减少了I/O操作,提高了类查找的速度。

下面我们新建两个java类文件,分别是Dex1.java和Dex2.java文件:

我们使用javac命令可以将java文件编译成class文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
javac Dex1.java
javac Dex2.java

使用jar命令将两个class文件打包成一个jar包:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
jar cvf AllDex.jar Dex1.class Dex2.class

上面的命令将两个class文件打包成了一个AllDex.jar的包。

最后使用dx命令将jar包优化压缩成class.dex文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dx --dex --output AllDex.dex AllDex.jar

打包之后的dex包,可以使用Android SDK中的dexdump工具进行查看:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dexdump -d -l plain AllDex.dex

需要注意的是,Android编译打包对class文件的压缩伴随着一个副作用,就是Android的65535的问题,这一问题最直接的原因就是DVM的源代码MemberIdsSection.java中:

此处规定了一个Dex文件中的方法、属性、类的个数不能超过MAX_MEMBER_IDX(65535),Android为了解决这一问题,提供了MultiDex来解决。

架构基于寄存器/基于栈结构

JVM的字节码指令的执行是基于栈进行的,而Android字节码指令的执行是基于寄存器的,这里的寄存器是在内存中模拟出的一组寄存器,而并非硬件的寄存器。Android和Java的字节码是完全不同的,Android的字节码是二地址或三地址的指令。

我们编写Dex.java文件:

java文件经过javac的编译打包之后的字节码:

使用dx对文件进行优化压缩之后的字节码文件:

Android字节码命令说明:

add-in指令需要三个寄存器参数,这个指令会将后面两个寄存器(v2、v3)相加,然后将结果寄存在第一个寄存器(v0)中;

return指令会将最终的结果返回。

可以看到在class字节码中需要4行的指令,经过Android优化压缩之后只有2行。基于寄存器的指令明显要比基于栈的指令少,虽然指令的长度增加,但是执行的速度得到了提高。

下面是基于栈和基于寄存器指令的对比:

内存管理和回收

DVM和JVM另外一个明显不同的地方就是内存结果的不同,主要体现在堆内存的划分和管理上。DVM中将堆内存分成了两部分:Active Heap和Zygote Heap。

为什么要区分Zygoto Heap和Active Heap

在Android系统中,底层init进程会创建一个Zygoto进程,Zygoto创建了Android中的DVM,其他的应用进程以及SystemService也都是由Zygote进程fork出来的。

Zygote进程在被创建之后,会完成虚拟机的初始化、lib库的加载、系统资源的配置等等,当系统需要创建一个新的应用进程的时候,Zygote通过复制快速fork出一个新的进程,对于一些只读的库和资源,所有的虚拟机实例都是和Zygote共享同一块内存区域,这样大大减小了内存的开销。Android将创建的进程的堆内存划分为两块,其中一块Zygote Heap,就是为了减少相同内容的拷贝,这部分堆内存所有DVM共享,而进程自己的数据读写全部在Active Heap中进行。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农帮派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android 进阶解密笔记-DVM与JVM
jvm基于栈则需要从栈中读写数据,所需的指令会更多,这样导致运行速度慢,这对于性能有限的移动设备不合适。DVM是基于寄存器的,它没有基于栈的虚拟机在复制数据时而使用大量的出入栈指令,同时指令更加紧凑,简单,基于寄存器的指令要大,但是指令数量减少,总的代码数并不会增加多少
Yif
2019/12/26
7680
DVM三问—说说虚拟机
上一节说了Android的五层架构,今天说说其中的Dalvik虚拟机,简称DVM。
码上积木
2020/11/24
9990
Android内存优化(一)DVM和ART原理初探
前言 要学习Android的内存优化,首先要了解Java虚拟机,此前我用了多篇文章来介绍Java虚拟机的知识,就是为了这个系列做铺垫。在Android开发中我们接触的是与Java虚拟机类似的Dalvik虚拟机和ART虚拟机,这一篇我们就来了解它们的基本原理。 1.Dalvik虚拟机 Dalvik虚拟机( Dalvik Virtual Machine ),简称Dalvik VM或者DVM。它是由Dan Bornstein编写的,名字源于他的祖先居住过的名为Dalvik的小渔村。DVM是Google专门为And
用户1269200
2018/02/01
1.5K0
Android内存优化(一)DVM和ART原理初探
Dalvik虚拟机
Dalvik虚拟机是google专门为android平台开发的一个java虚拟机,但它并没有使用JVM规范。Dalvik虚拟机主要完成对象生命周期的管理、线程管理、安全和异常管理以及垃圾回收等重要功能。  java虚拟机和Dalvik虚拟机的区别: java虚拟机 Dalvik虚拟机 java虚拟机基于栈。 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多 dalvik虚拟机是基于寄存器的 java虚拟机运行的是java字节码。(java类会被编译成一个或多
xiangzhihong
2018/01/30
1.3K0
Dalvik虚拟机
从JVM到Dalivk再到ART(class,dex,odex,vdex,ELF)
现在市面上的 Android 手机大部分都是运行的是ART虚拟机了。还记得自己一部 Android手机(HuaweiG520),Android4.1 系统。那时候还是没有 ART虚拟机 的。作为Android开发者,我们应该对 Android 的发展历史有些了解为什么 Android 会经历这么多的变化。Android 是先有 JVM 然后是 Dalvik ,接着是现在的 ART虚拟机 。那么他们之间有什么关系呢?
静默加载
2020/05/29
2.2K0
笔记——JVM、DVM(dalvik)和ART之间的区别(二十)
JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才能够运行Java程序,JAVA在编译后会生成类似于汇编语言的.class字节码文件,与C语言编译后产生的汇编语言不同的是,C编译成的汇编语言会直接在硬件上跑,但JAVA编译后生成的.class字节码是在JVM上跑,需要由JVM把字节码翻译成机器指令,才能使JAVA程序跑起来。
木溪bo
2019/08/06
3.2K0
Android内存管理(JVM 、DVM(dalvik) 、ART简单介绍)
本文不对JVM 、DVM(dalvik) 、ART这三者做具体的分析。只是从内存管理的角度来介绍下三者的区别和联系。
Anymarvel
2020/09/06
3.1K0
【Java 虚拟机原理】动态字节码技术 | Dalvik & ART 虚拟机 | Android 字节码打包过程
使用 Javassist 框架 , 可以自动查找要修改的内容所在字节码文件中的位置 , 不需要开发者自己手动分析 Java 字节码文件 ;
韩曙亮
2023/03/29
6740
【Java 虚拟机原理】动态字节码技术 | Dalvik & ART 虚拟机 | Android 字节码打包过程
Android-Dalvik虚拟机
Dalvik虚拟机作为Android平台的核心组件 1.体积小,占用内存空间小 2.专有的DEX可执行文件 体积更小 常量更快 3.常量池采用32位索引值 寻址类方法名 字段名 常量更快 4.基于寄存器架构 并拥有一套完整的指令系统 5.提供了对象生命周期管理 堆栈管理 线程管理 安全和异常管理以及垃圾回收等重要功能 6.所有的Android程序都运行在Android系统进程里 每个进程对应一个Dalvik虚拟机实例
tea9
2022/07/16
4580
JAVA虚拟机与Android虚拟机的区别
1.JAVA虚拟机运行的是JAVA字节码,Dalvik虚拟机运行的是Dalvik字节码 java虚拟机:JAVA->class文件 dalvik虚拟机:JAVA->class文件->Dalvik字节码->打包到dex中->DVM通过解释DEX文件来执行这些字节码。
老马的编程之旅
2022/06/22
1.2K0
JAVA虚拟机与Android虚拟机的区别
谈一谈Android内存
或许,因为开发周期的原因;因为自身知识水平的原因;因为经验的原因;又或者是你接了个烂摊子。我们写出了并不太理想的代码,这都是可以接受的,只要你会去持续优化,这些问题都会得到改善。而有些人是心有余而力不足,“我也想优化,可是怎么去优化呢?”。本篇文章将给你带来一点启示,让你从力不从心到知道怎么去入手优化。
吴延宝
2019/01/09
6450
浅谈 Android Dex 文件
了解了 Dex 文件以后,对日常开发中遇到一些问题能有更深的理解。如:APK 的瘦身、热修复、插件化、应用加固、Android 逆向工程、64K 方法数限制。
有赞coder
2020/08/25
6890
浅谈 Android Dex 文件
dex文件解析(第三篇)「建议收藏」
dex文件是Android系统中的一种文件,是一种特殊的数据格式,和APK、jar 等格式文件类似。 能够被DVM识别,加载并执行的文件格式。 简单说就是优化后的android版.exe。每个apk安装包里都有。包含应用程序的全部操作指令以及运行时数据。 相对于PC上的java虚拟机能运行.class;android上的Davlik虚拟机能运行.dex。
全栈程序员站长
2022/08/03
1.7K0
dex文件解析(第三篇)「建议收藏」
Android | 关于 OOM 的那些事
Android 系统对每个app都会有一个最大的内存限制,如果超出这个限制,就会抛出 OOM,也就是Out Of Memory 。本质上是抛出的一个异常,一般是在内存超出限制之后抛出的。最为常见的 OOM 就是内存泄露(大量的对象无法被释放)导致的 OOM,或者说是需要的内存大小大于可分配的内存大小,例如加载一张非常大的图片,就可能出现 OOM。
345
2023/05/26
1.7K0
Android | 关于 OOM 的那些事
Dalvik、ART与JVM之间的关系
01 — Dalvik简介 1、Google自己设计的用于Android平台的虚拟机; 2、支持已转化为dex格式的java应用程序运行; dex是专为Dalvik设计的一种压缩格式 3、允许在有限的内存中同时运行多个虚拟机实例,并未每一个Dalvik应用作为一和独立的Linux进程运行; 4、5.0以后,Google直接删除Dalvik,取而代之的是ART。 ---- 02 — Dalvik与JVM区别 1、Dalvik是基于寄存器,JVM基于栈; 2、Dalvik运行dex文件,JVM运行java字
蜻蜓队长
2018/08/03
1.4K0
dex优化对Arouter查找路径的影响
1、通过aapt打包资源文件res,对应生成R.java、resources.arsc和res文件(二进制&非二进制保持原来的代码)
2020labs小助手
2021/06/04
9380
JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比
JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才能够运行Java程序,JAVA在编译后会生成类似于汇编语言的JVM字节码,与C语言编译后产生的汇编语言不同的是,C编译成的汇编语言会直接在硬件上跑,但JAVA编译后生成的字节码是在JVM上跑,需要由JVM把字节码翻译成机器指令,才能使JAVA程序跑起来。
全栈程序员站长
2022/07/20
1.5K0
JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比
Apk 反编译前期了解
LZ-Says:学习之路,似乎枯燥乏味,唯有耐着性子,独自前行,当光明笼罩的那一刻,一切,也仿佛明亮了许多。
贺biubiu
2019/06/10
1.1K0
Java虚拟机和Dalvik虚拟机的区别java虚拟机和Dalvik虚拟机的区别
java虚拟机和Dalvik虚拟机的区别 该文章是本人转载的,觉得写的不错,和大家分享一下 Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野。它对内存的高效使用,和在低速CPU上表现出的高性能,确实令人刮目相看。 依赖于底层Posix兼容的操作系统,它可以简单的完成进程隔离和线程管理。每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例, 其代码在虚拟机的解释下得以执行。  很多人认为Dalvik虚
cMusketeer
2018/03/28
2.6K0
Java虚拟机和Dalvik虚拟机的区别java虚拟机和Dalvik虚拟机的区别
Java文件是如何编译成Dex文件的?如何执行Dex文件?「建议收藏」
Android系统中,一个App的所有代码都在一个Dex文件里面。Dex是一个类似Jar的存储了多有Java编译字节码的归档文件。
全栈程序员站长
2022/09/07
2.1K0
相关推荐
Android 进阶解密笔记-DVM与JVM
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验