Dalvik & ART

Dalvik

  • 相对于大多数的虚拟机是基于堆栈实现的,Dalvik是基于寄存器。
    • 一般来说,基于堆栈的机器必须使用指令才能从堆栈上的加载和操作数据,因此,相对基于寄存器的机器,它们需要更多的指令才能实现相同的性能。但是基于寄存器机器上的指令必须经过编码,因此,它们的指令往往更大。
  • Dalvik是即时编译(JIT)的,在程序运行的过程中,Dalvik虚拟机在不断的进行将字节码编译成机器码的工作。并且是每次运行都要转换,所以它的性能就非常的差。
  • Dalvik使得在有限的内存中可以同时运行多个虚拟机的实例,并且实例都作为一个独立的Linux进程执行。这样的好处就是,独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
  • JIT的引入使得dalvik提升了3~6倍的性能

ART

  • Android5.0全面支持
  • 预编译(AOT,Ahead-Of-Time),引入了AOT这种预编译技术,在应用程序安装的过程中,ART就已经将所有的字节码重新编译成了机器码。应用程序运行过程中无需进行实时的编译工作,只需要进行直接调用。
    • ART极大的提高了应用程序的运行效率,同时也减少了手机的电量消耗,提高了移动设备的续航能力,在垃圾回收等机制上也有了较大的提升。
    • 机器码占用的存储空间更大,字节码变为机器码之后,可能会增加10%-20%
    • 应用的安装时间会变长

两点提升

提高了内存使用和减少了碎片化

Dalvik采用的是Mark and Sweep算法来进行内存的回收,导致内存碎片化严重,并且降低了内存的使用率。

在art中,它将java分了一块空间命名为Large-Object-Space,这块内存空间的引入用来专门存放large object。同时art又引入了moving collector的技术,即将不连续的物理内存块进行对齐.对齐了后内存碎片化就得到了很好的解决。Large-Object-Space的引入一是因为moving collector对大块内存的位移时间成本太高,而且提高内存的利用率。

GC性能的提升

Dalvik存在的问题:

  • GC时挂起所有线程
  • 内存碎片化严重,大而连续的空间紧张

之所以要挂起所有线程是确保所有程序没有进行任何变更,与此同时GC会隐藏所有处理过的对象,最终,确保标记了所有需要回收的对象后,GC才会恢复所有线程,并释放空间。

ART的提升:

  • 如何解决GC挂去所有线程?
    • 在ART中GC会要求程序在分配空间的时候标记自身的堆栈,这个过程非常短,从而不需要挂去所有线程;
  • 如何解决大的空间紧张的需求?
    • ART里会有一个独立的LOS(large object sapce)供大空间使用,从而提高了GC的管理效率和整体性能。
  • 如何解决碎片化,内存使用率低的问题?
    • 在ART里还会有一个moving collector来压缩活动对象(绿色方块),使得内存空间更加紧凑。

results matching ""

    No results matching ""