简单聊聊JVM,DVM,ART

哈喽,大家好,这次我们来聊聊JVM和Andorid虚拟机的一些知识点。希望大家在看了文章后能对JVM,Dalvik,ART有一个简单的认识,如果想要详细研究的话,这篇文章还没有达到那个高度。好了,废话不多说,下面开始进入正题。


什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言只需生成在Java虚拟机上运行的目标代码(字节码/.class文件),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

什么是DVM(Dalvik)?

Dalvik是Google公司自己设计用于Android平台的Java虚拟机。它是在JVM的基础上做了进一步的改动,使其更好的适应于移动设备。Dalvik的指令集是基于寄存器来实现的,而JVM是基于堆栈来实现的。这使得前者在速度上比后者更好,同时会减少CPU压力。

JVM和DVM

Java执行的时候最终是将Java代码转换为.class文件,而因为.class文件存在很多的冗余信息,不太适合在移动设备上执行,所以Google在获取.class文件后利用DEX工具将.class文件整合为.dex文件,去除了.class文件的冗余信息,减少I/O操作,提高了查找速度。不过这样也导致了方法数超过65535。Google利用MultiDex技术将.dex文件转换为.odex文件,解决了方法数的问题。

JVM内存结构

在了解完JVM和DVM的关系后,我们来看看JVM的内存结构


jvm内存结构

图中蓝色代表线程共享,黄色代表线程私有。

  • 程序计数器:它是线程的一块私有内存,用来储存当前线程执行的字节码指令的内存地址。因为CPU的一个核心一次只能执行一个线程,所以多线程其实是在多个线程之间切换执行来实现的。这样在切换到一个线程后如何从正确的位置开始执行,就要找到储存的内存地址。

  • 虚拟机栈:它是一块线程私有内存,它的生命周期与线程相同。 Java虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动作链接、方法出口等信息。每个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

  • 本地方法栈:本地方法栈和虚拟机栈基本类似,只是虚拟机栈服务的是Java方法,而本地方法栈服务的是Native方法。

  • 方法区:方法区是线程共享的,它是用于存储类结构信息的地方。包括常量、静态变量、构造函数等类型信息。而前面所讲的类型信息是由类加载器在类加载时从类文件中提取出来的。运行时常量池是方法区的一部分。用于存放编译器生成的各种字面量和符号引用。运行期间也可以将新的常量放入常量池中,用得比较多的就是String类的intern()方法。当方法区内存使用满了后也会发生OOM。

  • 堆:它是虚拟机管理内存中最大的一块,被所有线程共享,该区域用于存放对象实例,几乎所有的对象(实例变量,数组)都在该区域分配,是GC的主要区域。

Dalvik的堆结构

因为Dalvik和JVM的堆结构有区别,所以我们这里来专门讲一讲Dalvik的堆结构。Android中是把堆结构分成了两部分,Active堆和Zygote堆。

Zygote是Android中的一个虚拟机进程,同时也是一个虚拟机实例的孵化器。Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等操作。在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供个进程。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。除了Zygote预加载的Android的核心类等,其余新建的实例,数组等都是放在Active堆中。因为Zygote堆中的类库我们很少 修改,所以Active是GC的重点,这也是把堆分成Zygote和Active的原因。

Zygote在创建一个新的虚拟机实例的时候用的是fork技术,为了尽可能的避免父进程和子进程之间的数据拷贝,fork方法使用写时拷贝技术,简单讲就是fork的时候不立即拷贝父进程的数据到子进程中,而是在子进程或者父进程对内存进行写操作时才对内容进行复制。

什么是ART?

这里先说说JIT和AOT这两个概念

  • Just In Time (JIT)
    使用 Dalvik JIT 编译器,每次应用在运行时,它实时的将一部分 Dalvik 字节码翻译成机器码。在程序的执行过程中,更多的代码被被编译并缓存。由于 JIT 只翻译一部分代码,它消耗的更少的内存,占用的更少的物理存储空间。
  • Ahead Of Time(AOT)
    ART 内置了一个 Ahead-of-Time 编译器。在应用的安装期间,它就将 dex 字节码编译成机器码并存储在设备的存储器上。这个过程只在将应用安装到设备上时发生。由于不再需要 JIT 编译,代码的执行速度要快得多。

ART是Android在5.0的时候使用的用来代替Dalvik虚拟机的,其实在4.4的时候ART就已经放入了代码中。Dalvik虚拟机当时用JIT技术,为了更好的提高Android设备性能, ART用了AOT技术,这样去除了运行时的解释执行,效率更高,启动更快。在带来更快的运行速度的同时,ART也有它的缺点。因为安装时要把dex文件编译成机器码存在本地,所以会占用更大的本地空间,同时安装时间也会较长。

ART堆结构

ART的堆结构相比于Dalvik有一定的改动,ART的堆主要组成包括Image Space、Zygote Space、Allocation Space和Large Object Space四个Space。其中Image Space、Zygote Space这两个为所有线程共享内存。Allocation Space和Large Object Space则拿来分配内存。

Large Object Space是用来分配内存给需要占用大内存的实例,数组。它需要满足一定条件才会分配

  • Zygote Space已经划分除了Allocation Space
  • 分配对象是原子类型数组,如int[] byte[] boolean[]
  • 分配的内存大小大于一定的门限值

当满足这三个条件后,就会分配Large Object Space中的内存。

在对ART的堆结构优化后,ART内存分配效率是Dalvik的8-10倍,GC效率是Dalvik的2-3倍。


到这里简单的介绍就够一段落了,希望大家有所收货。如果文章中有错误的地方,大家提出来后我会及时修改。

参考文献:
Android内存管理分析总结
JVM内存结构分析
JVM、DVM(Dalvik VM)和ART虚拟机对比
Android ART

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容