Android DVM

设计Android运行时需要考虑如下几点:

• 处理器速度
• RAM
• 没有交换空间
• 电池电量
• 各种各样的设备
• 应用程序沙盒

每一个Android应用程序运行在自己独立的进程中,该进程是一个Dalvik虚拟机实例。这样子一个设备上面就可以同时运行很多个Dalvik实例。Dalvik虚拟机执行的程序是经过内存优化的Dalvik可执行文件(.dex),dex是先通过Java编辑器编译为class文件

,然后通过dx工具处理得到的。Dalvik虚拟机不同于其他基于栈的虚拟机,是基于寄存器的虚拟机。Dalvik虚拟机依赖于linux内核提供的线程管理和内存管理等功能。

Dalvik虚拟机相关的主要内容包括:dex文件、Zygote和安全模型。下面分别讨论一下:

dex文件

dex文件文件的的详细格式可以参考http://www.retrodev.com/android/dexformat.html

Java代码编译后会给每个类创建一个class文件。比如你的一个Java文件总包含一个公开类,一个静态内部类,三个匿名类,编译过后将会得到5个class文件。也就是说一个class文件包含一个类。一个dex却可以包含很多类在里面。由于dex文件更加紧凑

,占用的内存空间更少,更重要的一点是实现了代码的共享。下面是一个详细的示意图,

可以看出jar与apk之间是等价的,都是对类、资源进行了打包。最大的不同是常量池的使用:Java中利用一个异构常量池将所有的符合都放在其中,不管其类型的什么,dex为不同的常量字段类型创建不同的常量池。好处在于非常清晰,类型也是明确

的。dex中所有的类都可以访问这些常量池,减少了常量在内存中的重复。而Java的异构常量池存在于每个类当中。

到底dex能够优化多少的内存空间呢?下面是一个对比结果。可以看出未经压缩的dex文件比压缩后的jar文件还小。

Code Uncompressed JAR Compressed JAR Uncompressed dex File (bytes)
Common System Libraries 21,445,320 (100%) 10,662,048 (50%) 10,311,972 (48%)
Web Browser App 470,312 (100%) 232,065 (49%) 209,248 (44%)
Alarm Clock App 119,200 (100%) 61,658 (52%) 53,020 (44%)

Zygote

Zygote是啥意思呢?[生物] 受精卵, 接合子, 接合体,可以繁殖出新的实例。由于每个应用都是运行在单独的Dalvik虚拟机进程上,能够快速创建新的应用实例和减少内存使用量成为了Android的一个基本需求。Zygote假定很多核心库及其堆结构会被许多应用同时使用,并且使用的方式是只读模式。

Zygote本身也是一个虚拟机进程,它在系统启动的时候就被创建了。Zygote一被创建,他就开始加载和初始化核心类库。由于这些类库都是只读的,一开始加载后,创建新进程直接使用父进程的内存空间即可,不需要重新加载和初始化。如果需要更改,写时复制技术可以将父进程的内存做个拷贝。从未保证应用程序不会干扰其他应用,提供了安全的访问模型。Zygote初始化完成后,它作为一个守护进程,在Socket上等待创建新的虚拟机实例的请求。

Zygote初始化完后, 会启动SystemService, 也是一个DVM进程。负责实例化系统Service和锁屏界面(StatusBar在Android2.2之前也是需要实例化的。Android2.3之后StatatusBar由SystemUI.apk实现,会开一个虚拟机进程)。

每个Activity在启动的时候会传递一个ContextImpl实例, ContextImpl用于访问系统服务的各个Manger(PackageManager, ActivityManager), Manager在调用对应的服务(资源加载(PackageManagerService), ActivityMangerService, MountService等)

Dalvik MicrosoftVM 依赖 Linux 内核获得基本功能,如线程处理和底层内存管理。

基于寄存器的Dalvik虚拟机

基于栈和基于寄存器的虚拟机各有优点,栈是在内存中的,基于栈的虚拟机可以提供后端的抽象,重点设计在前端,移植上比较方便。基于寄存器的虚拟机需要在后端实现虚拟机,而寄存器在不同的芯片上不一样的,因此设计上更加复杂具体,难以移植到别的芯片上。简单的代价就是性能,Android为了能提高运行速度采用基于寄存器的虚拟机也是情有可原了。

实验数据表明,基于寄存器虚拟机最后得到的代码会比基于栈的虚拟机多25%,另一方面通过dex文件减少的代码约为50%,综合下来,Android的代码还是会少占用25%的内存使用。

安全

Android的安全模型保证了缺省情况下,没有应用有权限执行影响到其他应用、系统或者用户的动作。包括访问用户的私有数据,比如联系人、邮箱;读写其他应用的数据;网络设备访问。

Android的安全是通过操作系统和应用框架两个方面来实现的,Dalvik 虚拟机不提供安全特性。在操作系统层面上,每个应用都被分配了一个用户ID,即Linux用户ID,Linux提供用户管理机制保障了,应用只能访问受限的资源。如果应用需要访问不属于自己的资源的权限,就需要在AndroidManifest.xml中声明自己的访问权限,这些权限在应用安装时提示用户。Android已经提供了很多权限:http://developer.android.com/reference/android/Manifest.permission.html。Android提供了运行时的权限控制类SecurityManager(http://developer.android.com/reference/java/lang/SecurityManager.html)。

更多Android安全相关的内容参考http://source.android.com/tech/security/index.html

 

Zygote 負責幾項重要的工作:

1. Listening Socket (Forking child process)
2. Preload Resource  Framework-res.apk等
3. Preload Class Framework.jar,Service.jar等
4. Start System Server 系统服务
5. Enter Zygote Fork Mode 在Socket端等待创建新DVM需求

Android 作業系統開機時,會經由 init.rc 來啟動許多外部程式,其中有一個最重要 process 稱為 Zygote。Zygote 是 Android 的 monitor process,它主要負責二項工作:

1. 啟動 system server
2. 執行 Android 應用程式

「System Server」是由 Zygote 所建立的另外一個 process,建立 system server 的方式是使用典型的 Linux system call - fork()。當 Zygote 成功建立 system server 後,便進入 socket listening 模式。在此模式下,zygote 會監聽(listen)由 socket 所傳入的「命令」,並依據命令的內容啟動 Android 應用程式。

Zygote 啟動外部 Android 應用程式的方式,同樣是使用 Linux kernel 所提供的 fork() system call。因此,在 socket 做 listening,並依據命令來 fork() 並執行外部 Android 應用程式,稱之為「Zygote Mode」

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值