Java Jvm、Android Dalvik和Android Art(二)——Android之路

Android dalvik

我们已经知道jvm,其实jvm和dalvik虚拟机共享差不多的特性,
例如,它们都是解释执行,并且支持即时编译(JIT)、垃圾收集(GC)、Java本地方法调用(JNI)和Java远程调试协议(JDWP)等。那么为什么Android不索性使用jvm呢?这是由于Android本身的使用场景和商业需求而决定的。大多数商业应用的技术都是在技术和商业需求的折衷。

言归正传,Android具有内存空间小,硬件功能差的特点,同时有要求良好的用户体验即实时性,良好的交互性能。所以为了适应这些要求,dalvik应运而生。

dalvik虚拟机和jvm的区别

为了适合在内存和处理器速度有限的手机系统中使用,dalvik虚拟机采用了不同于jvm的文件格式和指令集。Dalvik虚拟机使用的是dex(Dalvik Executable)格式的类文件,而Java虚拟机使用的是class格式的类文件。一个dex文件可以包含若干个类,而一个class文件只包括一个类。由于一个dex文件可以包含若干个类,因此它就可以将各个类中重复的字符串和其它常数只保存一次,从而节省了空间。

dalvik虚拟机使用的指令是基于寄存器的,而jvm使用的指令集(指令是一个字节所以称为字节码)是基于堆栈的。基于堆栈的指令更小。但是指令条数更多,这就意味着需要更多的CPU计算。而基于寄存器的指令较大(指令中需要指令源地址和目标地址),指令条数少,所以较少的需要CPU计算,更多的需要内存空间以存放指令。

AOT(本质为静态编译)和JIT(即时编译),JIT在运行时进行编译,即可以用运行时的信息进行代码优化,同时他需要运行的处理时间。AOT可以不计时间的进行代码优化,因为它是在运行前进行编译的。

不管结论如何,Dalvik虚拟机都在尽最大的努力来优化自身以适应需求,这些措施包括:

    1. 将多个类文件收集到同一个dex文件中,以便节省空间;

    2. 使用只读的内存映射方式加载dex文件,以便可以多进程共享dex文件,节省程序加载时间;

    3. 提前调整好字节序(byte order)和字对齐(word alignment)方式,使得它们更适合于本地机器,以便提高指令执行速度;

    4. 尽量提前进行字节码验证(bytecode verification),提高程序的加载速度;

    5. 需要重写字节码的优化要提前进行。
》内存管理

dalvik虚拟机的内存大体上可以分为Java Object Heap、Bitmap Memory和Native Heap三种。

这个Java Object Heap的最大值也就是我们平时所说的Android应用程序进程能够使用的最大内存。这里必须要注意的是,Android应用程序进程能够使用的最大内存指的是能够用来分配Java Object的堆。

Bitmap Memory也称为External Memory,它是用来处理图像的。但这部分内存同样计入Java Object Heap中,也就解释了为什么处理大图像会产生OutOfMemoryError异常。

Native Heap就是在Native Code中使用malloc等分配出来的内存,这部分内存是不受Java Object Heap的大小限制的,也就是它可以自由使用,当然它是会受到系统的限制。

》垃圾回收(GC)

补充上一节的内容,C++和java中内存泄露的差别,如图:
这里写图片描述

dalvik虚拟机中的GC和jvm的GC没有太大差别,基本的算法与实现看上一节内容。
需要强调的是在早一点的Android系统中GC是非并行的,GC是终止用户操作,用户会明显的感到卡顿。在高版本中GC已经实现了并行。

》进程和线程管理

一般来说,虚拟机的进程和线程都是与目标机器本地操作系统的进程和线程一一对应的,这样做的好处是可以使本地操作系统来调度进程和线程。进程和线程调度是操作系统的核心模块,它的实现是非常复杂的,特别是考虑到多核的情况,因此,就完全没有必要在虚拟机中提供一个进程和线程库。
》》进程的特点:

  • 每一个Android应用程序进程都有一个Dalvik虚拟机实例。这样做的好处是Android应用程序进程之间不会相互影响,也就是说,一个Android应用程序进程的意外中止,不会影响到其它的Android应用程序进程的正常运行。
  • 每一个Android应用程序进程都是由一种称为Zygote的进程fork出来的。Zygote进程是由init进程启动起来的,也就是在系统启动的时候启动的。Zygote进程在启动的时候,会创建一个虚拟机实例,并且在这个虚拟机实例将所有的Java核心库都加载起来。每当Zygote进程需要创建一个Android应用程序进程的时候,它就通过复制自身来实现,也就是通过fork系统调用来实现

本文是对http://blog.csdn.net/luoshengyang/article/details/8852432的个人理解。详细内容参考上文.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值