带你读《深入理解Android:Java虚拟机ART》之一:本书必读

移动开发

深入理解Android:Java虚拟机ART

邓凡平 著

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

第1章

本书必读

1.1 概述

笔者写书向来是最后才写第一章。此时,全书的主体内容已完全确定,笔者在学习ART虚拟机以及编撰本书的过程中所遇到的问题、总结的经验和教训等才可以完整地汇总并分享给各位读者。所以,本章是全书的点睛之笔,为必读章节。并且,我相信随着读者阅读的深入,还会时常回顾本章。
总体来说,本书并不简单。其实,从本书的目标—Java虚拟机也可以想得到,对Java应用程序来说,虚拟机就算是操作系统了。哪一本讲操作系统的书会简单呢?
具体到Android ART虚拟机来说,本书以Android 7.0为参考,绝大部分待分析的源代码位于art目录中。
□包含C++代码1071个文件。其中,.cc文件中包含236 744有效代码行(即不算注释及空行),.h文件中包含74 710有效代码行。
□包含汇编文件1704个文件,覆盖x86、arm、mips的32位和64位6个CPU平台,有效代码共19 955行。
也就是说,我们的ART虚拟机是一个有着30多万行代码的庞然大物。针对这样一个复杂的系统,要想从一个对它略知一二的初学者成长为一个能品头论足甚至指点*的熟练者,这一路的学习历程必然不会轻松。
接下来,笔者将介绍阅读本书时必须准备的工具。磨刀不误砍柴工,建议读者先把这些工具准备好之后再开始后面的学习。

1.2 准备环境和工具

为了更好学习ART,读者要准备好如下的环境或工具。

1.2.1 准备源代码

首先,我们需要一份Android 7.0的源代码。笔者在百度云盘上提供了本书所需的资料下载。读者也可以到清华大学开源软件镜像站按照网页里的说明下载。其官网地址为https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/。笔者总结其下载步骤如下。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

源代码的量很大,读者需要有一个浏览它的工具,Source Insight是不二之选。下面我们来看看如何配置它。

1.2.2 准备Source Insight

Source Insight是阅读源码的必备工具,它是一个Windows软件,在Linux平台上可通过wine进行安装。
提示:Source Insight推出3.5版本之后,很长一段时间都没有更新。最近推出了全新的4.0版本。但经过笔者测试,4.0版本的Source Insight在Linux上表现不稳定,建议读者在Linux上使用3.5版本的Source Insight。下面的讲解也以3.5版本的Source Insight为主。
首先,打开Source Insight,通过菜单项Project→New Project新建一个源码工程。工程可建立在Android 7.0源码根目录。笔者存放的位置是~/workspace/aosp/android-7.0,工程名为android-7.0。
接下来我们要先设置源码文件的后缀名。在ART中,C++的实现文件以.cc为文件后缀名。而汇编源码存储在以.S为后缀的文件里。Source Insight默认的配置不识别.cc和.S为后缀的源码文件,所以我们需要修改它。
单击菜单项Options→Document Options,弹出图1-1所示的文件类型对话框。
图1-1用于为C++源码添加.cc结尾的文件类型。接着还要为汇编源码做类似的处理,来看图1-2。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

接下来我们为android-7.0工程添加具体的源码文件。单击菜单项Project→Add and Remove Project Files,弹出工程文件选择对话框,如图1-3所示。
请读者添加如下目录到android-7.0工程中。
□art目录(通过图中的Add Tree按钮可添加整个目录):ART虚拟机源码文件。
□libcore目录:包含JDK相关源码文件。
□libnativehelper目录:包含JNI相关源码,如jni.h等。
□frameworks/base/cmds/am、frameworks/base/core、frameworks/base/include三个目录:包含Zygote相关源码文件。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

另外,上述目录中还有很多用于测试的源码文件,数量非常多。由于它们对本书的学习并无影响,建议读者移除其中test目录下的源码文件—通过图1-2中的Remove Tree可移除指定目录中的源码。比如art/test包含的1800多个源码文件都可以移除。
接着要进一步配置Source Insight。ART是一个复杂系统,所以谷歌用了一些工具来辅助编写正确的源码。这些工具要求在源码函数声明、变量定义等地方使用一些特殊的宏,而Source Insight不认识这些宏,所以很多函数、变量都无法解析和识别。为此,我们需要配置Source Insight,让它忽略这些宏。配置方法下面将详细介绍。
首先,找到Source Insight的C.tom文件,它位于~/.wine/drive_c/Program Files (x86)/Source Insight 3/下。打开该文件,在文件末尾添加如下的内容。
[C.tom文件]
;C.tom是C Token Macros的意思,用于重定义C/C++文件中的宏
;下面的条目都是ART源码中出现的宏,我们将它们定义为空,这样,Source Insight碰到这些宏
;时就会忽略它们
SHARED_TRYLOCK_FUNCTION(...)
ACQUIRE_SHARED()
EXCLUSIVE_TRYLOCK_FUNCTION(...)
SCOPED_CAPABILITY
SHARED_REQUIRES(...)
REQUIRES(...)
UNLOCK_FUNCTION(...)
ASSERT_SHARED_CAPABILITY(...)
ASSERT_CAPABILITY(...)
__noreturn
__mallocfunc
EXCLUSIVE_LOCKS_REQUIRED(...)
LOCKS_EXCLUDED(...)
SHARED_LOCKS_REQUIRED(...)
SHARED_LOCK_FUNCTION(...)
DEFAULT_MUTEX_ACQUIRED_AFTER
ACQUIRE(...)
ACQUIRE()
RELEASE()
RELEASE_SHARED()
ACQUIRED_AFTER(...)
GUARDED_BY(...)
PACKED(...)
__nonnull(...)
OVERRIDE
SHARED_LOCKABLE
ATTRIBUTE_UNUSED
NO_THREAD_SAFETY_ANALYSIS
ALWAYS_INLINE
配置好C.tom后,关闭并重新打开Source Insight,单击Project→Rebuild Project,弹出图1-4所示的对话框。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

图1-4中,选择Re-Create the whole project from scratch即可。
提示:图1-4所示对话框的下方展示了源码文件个数,笔者设置的工程包含源码文件8688个。

1.2.3 准备模拟器和自制系统镜像

阅读源码是学习虚拟机的主要方法。但在某些关键地方,有时候很难确定代码逻辑的走向,这时就需要在源码中加一些日志来辅助我们观察虚拟机的行为。在此,笔者推荐使用模拟器和自制系统镜像来帮助我们达到这个目标。
提示:自制系统镜像是由上文下载的Android源码文件编译而来。我们可以随心所欲地通过修改源码文件来定制Android系统。当然,这个由我们自己编译而来的系统只能跑在模拟器中。即便如此,这对我们学习ART虚拟机来说也是莫大的帮助。

1.2.3.1 准备好模拟器

读者需首先安装Android Studio。然后随便打开一个Android应用工程。单击菜单栏右边的avd manager图标,启动AVD界面,如图1-5所示。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

图1-5中,笔者创建了两个虚拟设备,一个是运行Android 7.0系统的innost-7.0设备,一个是运行Android 9.0系统的innost-9.0设备。
单击图1-6中左下角的“Create Virtual Device”,出现图1-6所示的设备硬件配置界面。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

读者可自定义硬件配置或者从谷歌相关手机产品中选一个手机型号。比如Pixel XL。然后单击图1-6右下角的Next。出现图1-7所示的系统镜像选择界面。


带你读《深入理解Android:Java虚拟机ART》之一:本书必读

建议读者选择Nougat x86系统镜像。也就是说,我们后面要分析的ART虚拟机将以x86 CPU为平台。
为什么选择x86平台?
工作用的台式机或笔记本主要是x86平台。所以,模拟器运行x86系统镜像的速度非常快。笔者之前尝试过使用arm平台,但模拟器运行的速度较慢。另外,根据上一节笔者统计的代码量可知,6个CPU平台总汇编代码的有效代码行数/总有效代码行数大概为6.02%,平均每个CPU平台的汇编代码行数才占总代码行数的1%左右。从这一点可以看出,汇编代码虽然重要,但它不会影响虚拟机学习。值得注意的是,Android SDK从8.0开始就不再提供ARM平台的模拟器镜像文件。
虚拟设备准备就绪后,读者可以启动它。这时,这个虚拟设备运行的是官方提供的镜像。

1.2.3.2 自制系统镜像

现在,我们有了Android源码、虚拟设备和官方下载的镜像文件。接下来需要编译Android源码以生成一个系统镜像文件,然后用这个系统镜像文件来启动虚拟设备。如此,就达到了让虚拟设备运行我们定制的系统镜像的目标。
编译系统的步骤如下。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

执行lunch命令后,会显示如图1-8所示的内容,里边是各种不同的目标设备。请读者选择第8项(下面将介绍第8项的来历)。它表示要编译设备类型为"innost"的设备,该设备使用的CPU为x86,编译类型为userdebug。接着看下一步。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

最后,让模拟器使用我们编译得到的系统镜像文件,方法如下。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读


带你读《深入理解Android:Java虚拟机ART》之一:本书必读


由于本书的目标是研究ART虚拟机,所以,我们自己编译的系统镜像并不需要包含太多的应用程序,只要保证系统启动必需的几个核心应用程序即可。为此,笔者在源码根目录/device下新增了一个名为innost的设备类型。图1-9展示了该目录下的文件。
图1-9展示了innost设备类型下包含的文件。当把这些准备好后,我们执行如下命令时才能出现图1-8中的第7和第8项。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

提示:读者可从笔者分享的链接中下载如图1-9所示的innost设备目录文件。本书所有资源的下载说明见1.4节的内容。
如果读者下载了笔者分享的Android 7.0源码的话,device目录下已经包含了innost设备目录的文件。

1.2.4 小结

读者阅读到这个地方时,请检查下面的工作是否完成。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

□有一份完整的Android 7.0的源码。读者可以从笔者提供的资源链接中下载,或者从清华大学开源镜像站下载(下载步骤见1.2.1节)。
□配置好Source Insight,包括添加.cc和.S为后缀的文件类型、修改C.tom文件。然后,导入ART虚拟机学习所需的源码目录(art、libnativehelper、libcore、frameworks/base/cmds/am、frameworks/base/core、frameworks/base/include,可以把test相关的源码去除)。
□下载Nougat x86系统镜像,创建好对应的模拟器,并启动它。
□编译7.0的源码。如果读者是自行下载的源码,请从笔者提供的资料链接中下载自制系统镜像所需的设备配置文件(存放在源码根目录/device下)。
□通过emulator命令使用自己编译出来的系统镜像文件启动模拟器。

1.3 本书的内容

本书大体上可以分为五个部分,笔者用表1-1来描述各个部分对应章节的内容和说明。请读者务必认真阅读(后续如果需要,也请经常回顾)。
提示:表1-1最后一列是笔者给各章节难度的一个主观评分。评分的目的在于提醒读者阅读各章时可能会感受到的难度。除了第6章有着超高难度之外,其他章节只要肯花时间,相信对大部分读者总能学会。另外,笔者自己在研究ART源码的时候会碰到这样一种情况,有些代码前几次阅读感觉难度比较大,但只要多读几次,总会有茅塞顿开的时候。或许这就是所谓的量变到质变吧。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读
带你读《深入理解Android:Java虚拟机ART》之一:本书必读

笔者再次和读者强调两点:
□ART虚拟机是复杂系统,模块之间有非常强的耦合关系。读者需采用剥洋葱式的学习方法,逐步、多角度来学习它。比如,Heap模块本书有三处地方介绍了它。每一次介绍都只关注Heap模块一部分的知识。初学者切莫盯着一个知识点一头扎入,否则很难走下去。
□如果读者不是特别了解ART的话,建议严格按照本书的顺序来阅读相关章节。

1.4 本书资源下载说明

读者可通过笔者的博客blog.csdn.net/innost首页置顶文章“深入理解Android系列书籍资源分享更新”以查看本书的资源下载地址。目前本书提供的下载资料如表1-2所示。

带你读《深入理解Android:Java虚拟机ART》之一:本书必读

如果说ART虚拟机是一座坚固的城堡的话,本书相当于在这个城堡上为读者们打开了好几个关键突破口。希望读者在此基础上继续研究ART虚拟机中其他有意思、有价值的领域。

上一篇:[C#]对Excel的操作


下一篇:JavaScript-----------基本包装类型