首页 > 编程知识 正文

安卓虚拟机机制,android jetpack mvvm

时间:2023-05-06 13:54:19 阅读:170324 作者:2835

我有段时间没更新博客了,有什么事一定有妖怪。 首先,从:开始阐述写这个系列博客的理由

这期间,上司的思想又变得有点邪恶了,总是想破解别人的软件,所以请让我研究一下。 于是我无暇询问,决定从java字节码指令集和dalvik虚拟机的arm指令集开始。 后来被非安全领域的专家放弃了,但研究对技术来说没有失去价值,成为了这个博客。

当然,这个博客只分析了Java字节码分析和Android的机器码分析,所以不能先消除邪恶的想法。 当然,有条件的学生,只要理解这一篇的智慧,应该不难。 回到正题,接下来一起揭开JVM和ARM指令集的神秘面纱吧。

要理解本章的内容,首先提出几个问题。

1.JVM、Dalvik和Art是什么? 他们的区别是?

2.class和. dex的区别?

3 .寄存器和虚拟堆栈是什么? 他们的优缺点是什么?

抱着以上问题,具体分析一下吧。 首先,前面的java虚拟机和Android虚拟机的内部结构图为以下:

从以上结构图可知,java虚拟机和Android虚拟机唯一的不同在于执行引擎不同,jvm执行字节码指令,Android虚拟机执行机器代码指令.

感兴趣的人可以深入分析每个模块的细节。 在这里贴上图,不要多叙述

为了分析jvm执行引擎和Android虚拟机执行引擎之间的差异,请编写代码以详细说明:

类中包含声明变量相加的方法,如以下代码所示

public class test { public void sumint (} { inta=2; int b=3; int c=a b; 返回; }使用编译工具将}Java字节码分析转换为. class字节码。 这个字节码是二进制文件,所以用文本视图工具看不到。 必须使用JDK的javap工具进行分析,在Win R中调用命令行窗口,并输入以下命令

javap -v -c -s -l Test.class可以看到下图,内容是

其他的都不用看。 请直接看红框标记的内容,将其复制并分析: (有关jvm命令,请参阅https://blog.csdn.net/u 012070360/article/details/81624854。 )

基础知识补充:int取值-1~5时为iconst命令,取值-128~127时为bipush命令,取值-32768~32767时为sipush命令,取值- 2147483648~214778 使用int型常量2推至栈顶1: istore_1 //int型,推至局部变量表中的第一位置2: iconst_3 //int型常量3推top:istore_2/等待将推送局部变量推送至int推送局部变量表中的第二个位置4: iload_1 //int类型加载局部变量表中第一个位置的局部变量被推送int类型加载局部变量表中第二个位置的局部变量被推送至堆栈顶部6: iadd //int类型,7: istore _3//这里使用图来帮助分析上面的字节码

安卓虚拟机命令分析

同样, dex是通过编译. class文件创建的。 这意味着. class是Android的中间过渡文件,所以首先在android sdk下使用dx批处理命令从. class打包dex文件。 class的路径必须添加环境变量或将class文件复制到名为sdk的目录中。 (

这里,根据命令一口气执行命令:

dx---dex---verbose---dump-to=test.dex.txt---dump-method=test.sumint-- verbose-dump Tet

请整理一下

0000: const/4 v0, 加载#int2//#2//int类型的常量2,为v00001: const/4 v1分配4字节内存,为#int 3 //#3 //加载的常量3分配4字节内存v1 //v0

通过以上分析,对上述几个问题回答如下。

问题1 :

对于JVM和Android虚拟机:

1.class在JVM上运行, dex在Andr上运行

oid虚拟机上;

2.JVM运行字节码存在冗余信息,Android虚拟机运行机器码去除了冗余信息;

3.JVM是基于虚拟栈的结构,Android虚拟机是基于寄存器结构;

针对Dalvik和Art:

1.Dalvik环境下需要每次在程序运行是通过即时编译器(JIT)将字节码转换成机器码,即每次都要编译加运行,虽然这样提升了安装速度,但会拖慢应用每次启动的效率;

而Art环境下,在安装时字节码就会预编译(AOT)成机器码,虽然安装的时间变长了,但是以后每次启动执行都可以直接运行,运行效率会提高,也就是典型的空间换时间的模式;

2.由于Art通过预编译成机器码,所以会比Dalvik占用更多的存储空间,也由于这个特性,因此不用每次运行前都要先编译,从而减少了CPU的使用率,降低了能耗;

问题2:

1.dex减少了整体的文件尺寸,就像是一个压缩文件,可以表示更多的类,而class则像是单个的文件;

2.Android虚拟机加载类时,只对dex进行一次IO操作可以加载很多类,而多个class则需要多次IO才能完成加载,提高了查找速度;

3.class指令较多,dex指令更加密集;

4.dex指令方便寻址,而class需要多次入栈(load)和弹栈(store)指令;

5.class适用于PC大内存,单指令小的情况快速运行,dex适用于移动设备性能不太高的要求;

问题3:

1.虚拟栈是通过无变量声明来操作虚拟机执行,使用的指令只占一个字节,由于使用栈操作,使指令变得很紧凑,但由于load/store的频繁调用,意味着更多的指令分派次数和内存访问次数,访问内存是执行速度的一个重要瓶颈;

2.寄存器是通过变量寻址来达到操作虚拟机执行,由于需要指定源地址和目标地址,所以每条指令需要占用更多的空间,但总体可以用更少的指令完成操作,指令分派和内存访问次数都较少,但由于访问内存次数较少,数据缓冲更易失效;

综上,基于栈的操作需要更多的指令,而基于寄存器则需要更多的指令空间。栈需要更多的指令意味着需要占用CPU更多的时间,寄存器需要更多指令空间意味着数据缓冲更易失效。是否基于虚拟栈和寄存器最本质的区别就是有无变量声明。

总结

JVM指令明显更多,更消耗CPU,由于每个指令只占1个字节,占用空间少;

Android虚拟机指令少,由于指令分配了源地址和目的地址,使得指令空间变大,更浪费空间

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。