《深入理解Android:Java虚拟机ART》

举报
华章计算机 发表于 2019/12/18 21:35:15 2019/12/18
【摘要】 本节书摘来自华章计算机《深入理解Android:Java虚拟机ART》 一作者是邓凡平。

移动开发

深入理解Android:

Java虚拟机ART

1576675150582532.jpg

邓凡平 著

 

 

 

 

Foreword  推荐序

重塑科技引领动能,打造科技金融银行

近几年,随着移动互联、云计算、大数据及人工智能等新兴技术的广泛应用,全社会已经进入了一个由移动互联网构成的高度数字化时代,而数字化浪潮则将金融机构带入到了由线上支付商、互联网巨头以及其他金融科技创新企业共同竞争的新金融生态圈。

从支撑到伙伴,再到引领,科技角色重新定位。一直以来,科技在银行中扮演更多的是支撑者的角色,在确保系统安全稳定运行的基础上配合业务进行需求开发。面对时下金融科技蓬勃发展的大潮以及互联网企业给传统银行业带来的冲击,银行业科技唯有主动出击,驱动业务转型,才能在冲击中乘风破浪,重塑商业银行在新时代的竞争优势。

面对数字化发展趋势带来的冲击和挑战,民生银行信息科技部积极践行科技引领理念,建设智慧银行。一方面在人工智能、云计算、物联网、区块链等新兴技术领域深入研究,大胆创新业务模式,实现重点领域突破。另一方面积极营造创新机制,推动“轻组织”改革,鼓励员工创新,并成立了专门的创新研发组织,推动科技创新。

本书作者来自民生银行信息科技部的创新技术研究院物联网团队。该团队主要研究物联网技术并积极探索其在金融领域中的应用。众所周知,物联网离不开数以亿计的各色终端设备,而基于安卓系统的智能设备又属于其中功能最为强大和完善的一种。对安卓系统的了解将有助于我们更好地将这种类型的设备应用于物联网或相关领域。

本书聚焦于安卓智能设备上Java虚拟机这一核心的底层技术实现。通过扎实和细致的源代码分析,对JVM进行了较为全面和深入的剖析,其详尽程度以及深厚的理论功底使得本书在理论研究和实践应用方面都颇具特色,相信本书可以有效提升读者在相关领域的开发能力。

牛新庄 博士。现任中国民生银行总行信息科技部总经理,民生科技有限公司执行董事、总经理。国务院互联网+行动专家咨询委员会专家,也是国内顶尖数据架构与科技治理专家。同时担任浙江大学等高校的兼职教授和客座教授。曾获“IBM杰出软件专家奖”“中国杰出数据库工程师奖”“IT168技术卓越奖”。拥有OCP、AIX等20多项国际认证。著有《DB2性能调整和优化》等书。

 

 

 

 

Preface  前  言

本书主要内容及特色

本书是笔者“深入理解Android”系列的第四本。本书将关注Android系统中至关重要的部分—Java虚拟机ART。市面上介绍Java虚拟机的书籍非常多,但鲜少有书籍能从虚拟机源代码出发对其进行详细分析。随着Android设备的大规模普及,ART虚拟机已经成为当今使用最为广泛的JVM之一。所以,对ART虚拟机进行研究有着非同寻常的意义。本书的出现在一定程度上填补了这方面的空白。

本书的主要内容概述如下:

第1章介绍ART虚拟机学习前需要准备好的工具、环境等。

第2章介绍Class文件的格式及内容。

第3章介绍Android中Dex文件的格式。

第4章介绍ELF文件格式。

第5章介绍C++11相关的、能帮助读者阅读ART源码的必备知识。

第6章以编译原理为基础,介绍ART虚拟机编译相关的知识。

第7章以ART Runtime对象的创建为主线,介绍主要的模块及一些关键类、数据结构等知识。

第8章以ART Runtime的Start为主线进行分析,覆盖的内容包括相关模块的启动、类的解析、加载、链接、初始化等。

第9章介绍dex字节码转机器码的核心进程dex2oat以及.oat和.art文件格式。

第10章介绍虚拟机的解释执行和JIT部分以及异常的投递和处理的过程。

第11章介绍JNI在ART虚拟机的实现。

第12章介绍虚拟机Java线程执行相关的知识,包括线程暂停和恢复运行、synchronized、Object wait/notify的实现、volatile变量的读写处理等。

第13章介绍内存分配和释放相关的知识。包括ART虚拟机中的各种Space类型、new指令的实现以及ART虚拟机中Heap模块的部分内容。

第14章介绍和垃圾回收有关的基础知识以及相关垃圾回收器,还有Java Reference的处理以及Heap模块的部分内容。

本书通过理论和代码相结合的方式进行讲解,旨在引领读者一步步了解Android系统中JVM的工作原理。

读者对象

Android系统开发工程师

系统开发工程师常常需要深入理解Android平台上各个系统的运转过程。本书所涉及的Java虚拟机是从事相关工作的读者在工作和学习中最想了解的。

Android应用开发工程师

Android应用开发工程师所开发的程序是运行在JVM中的。如果能更深入地了解JVM的实现将极大帮助开发工程师写出更高质量的程序。

对JVM感兴趣的在校高年级本科生、研究生等研究人员

JVM的理论书籍非常多,但很少有从分析源代码的角度来介绍其工作原理的。这本理论与代码实现深度结合的书籍一定可在该领域助相关研究人员一臂之力。

如何阅读本书

本书是一本有一定深度的书籍,所以读者在阅读时:

请务必首先阅读第1章。后续如果碰到阅读上的困难,可能还需时常回顾第1章。

本书的内容是经过笔者精心编排的,如果读者不是很有把握的话,建议严格按照顺序阅读。

本书的某些章节涉及了笔者在撰写它们时所参考的资料。这些资料较多,读者可根据它们开展进一步的研究工作。

另外,和笔者之前出版的《深入理解Android》卷Ⅰ以及卷Ⅱ类似的是:本书在每章开头都把本章涉及的源码路径全部列出,而在具体分析源码时,则只列出该源码的文件名及所分析的函数或相关数据结构名。例如:

[AndroidRuntime.cpp->AndroidRuntime::start]

//这里是源码分析和一些注释

最后,本书在描述类之间的关系及函数调用流程上,使用了UML的静态类图及序列图。UML是一个强大的工具,但它的建模规范过于繁琐,为更简单清晰地描述事情的本质,本书并未完全遵循UML的建模规范。这里仅举两例,如图1和图2所示。

在图1中:

外部类内部的方框用于表示内部类。另外,外部类A、内部类B也用于表示内部类。

接口和普通类用同一种框图表示。

图2所示为本书描述数据结构时使用的UML图。

 image.png

图1 UML示例图之一

 image.png

图2 UML示例图之二

图2为本书描述数据结构及成员时使用的UML图例。

特别注意 本书使用的UML图都比较简单,读者不必花费大量时间专门学习UML。另外,出于方便考虑,本书所绘制的UML图没有严格遵守UML规范。这一点敬请读者谅解。

本书涉及的Android源码及一些开发工具的下载可通过笔者的博客blog.csdn.net/innost首页置顶文章“深入理解Android系列书籍资源分享更新”查看。关于它们的使用详情,请读者阅读本书第1章了解。

勘误和支持

由于作者的水平有限,加之编写时间仓促,书中难免会出现一些错误或不准确的地方,恳请读者不吝赐教。若有问题,可通过邮件或在博客上留言与笔者共同商讨。笔者的联系方式如下:

邮箱fanping.deng@gmail.com

博客blog.csdn.net/innost

致谢

本书的顺利出版首先要感谢杨福川编辑的大力支持。另外,要感谢张锡鹏编辑在审稿期间严谨负责的工作。

另外,笔者需要特别感谢现就职的民生银行总行信息科技部。这是笔者第一次供职于一家金融企业。在此工作的这段时间里,我深刻体会到了民生科技人勇于开拓、锐意创新的精神气质,同时也感受到“金融科技为银行创造价值”的深远意义和重大责任。在此,笔者借助本书对相关领导和同事表示衷心的感谢。他们是牛新庄、毛斌、李建兵、林冠峰、李彧、娄丽明、侯佳腾、常薇、王连诚、张梦涵、侯超、金西银、孙升芸、孟凡娇、文静、赖穆彬等。正是你们的鼓励、支持和信任才使我的业余研究成果得以成书。

当然,本书能快速出版,还需要感谢几位功力深厚并热心参与技术审稿的专家。他们是滴滴出行资深研发工程师孙鹏飞和赵旭阳、高通无线半导体技术有限公司资深工程师钟长庚。几位专家在各自领域所体现出来的专业素养和技术水平之高时刻提醒笔者应牢记“路漫漫其修远兮,吾将上下而求索”。另外,其他几位小伙伴罗迪、段启智、高建武、陈永志也对本书的编写提供了不小的帮助。在此一并感谢他们。

最后,一如既往地感谢家人和妻子。另外,特别感谢索菲娅小朋友,正是她不厌其烦地问“爸爸,你为什么看电脑呀”,才使得笔者不得不加快编写速度。最后,感谢所有花费宝贵时间和精力关注本书的读者以及所有在人生和职业道路上曾给予我指导的诸位师长。

 

邓凡平

北京

 

 

 

Contents  目  录

推荐序

前言

第1章 本书必读1

1.1 概述1

1.2 准备环境和工具2

1.2.1 准备源代码2

1.2.2 准备Source Insight2

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

1.2.4 小结8

1.3 本书的内容9

1.4 本书资源下载说明12

第2章 深入理解Class文件格式13

2.1 Class文件格式总览13

2.2 常量池及相关内容14

2.2.1 常量项的类型和关系14

2.2.2 信息描述规则18

2.2.3 常量池实例剖析19

2.3 field_info和method_info19

2.4 access_flags介绍21

2.5 属性介绍22

2.5.1 属性概貌22

2.5.2 Code属性23

2.5.3 LineNumberTable属性25

2.5.4 LocalVariableTable属性26

2.6 Java指令码介绍27

2.6.1 指令码和助记符27

2.6.2 如何阅读规范28

2.7 学习路线推荐30

2.8 参考资料30

第3章 深入理解Dex文件格式31

3.1 Dex文件格式总览31

3.1.1 Dex和Class文件格式的区别31

3.1.2 Dex文件格式的概貌35

3.2 认识Dex文件36

3.2.1 header_item36

3.2.2 string_id_item等37

3.2.3 class_def38

3.2.4 code_item40

3.3 Dex指令码介绍41

3.3.1 insns的组织形式41

3.3.2 指令码描述规则42

3.4 学习路线推荐44

3.5 参考资料45

第4章 深入理解ELF文件格式46

4.1 概述46

4.2 ELF文件格式介绍46

4.2.1 ELF文件头结构介绍47

4.2.2 Linking View下的ELF52

4.2.3 Execution View下的ELF61

4.2.4 实例分析:调用动态库中的函数65

4.2.5 ELF总结72

4.3 学习路线推荐73

4.4 参考资料73

第5章 认识C++1174

5.1 数据类型76

5.1.1 基本内置数据类型介绍76

5.1.2 指针、引用和void类型77

5.1.3 字符和字符串81

5.1.4 数组82

5.2 C++源码构成及编译83

5.2.1 头文件示例83

5.2.2 源文件示例85

5.2.3 编译86

5.3 Class介绍88

5.3.1 构造、赋值和析构函数89

5.3.2 类的派生和继承97

5.3.3 友元和类的前向声明103

5.3.4 explicit构造函数105

5.3.5 C++中的struct106

5.4 操作符重载106

5.4.1 操作符重载的实现方式107

5.4.2 输出和输入操作符重载108

5.4.3 ->和*操作符重载110

5.4.4 new和delete操作符重载111

5.4.5 函数调用运算符重载117

5.5 函数模板与类模板118

5.5.1 函数模板119

5.5.2 类模板122

5.6 lambda表达式125

5.7 STL介绍127

5.7.1 string类128

5.7.2 容器类129

5.7.3 算法和函数对象介绍134

5.7.4 智能指针类138

5.7.5 探讨STL的学习140

5.8 其他常用知识141

5.8.1 initializer_list141

5.8.2 带作用域的enum141

5.8.3 constexpr142

5.8.4 static_assert143

5.9 参考资料143

第6章 编译dex字节码为机器码145

6.1 编译器全貌介绍147

6.2 编译器前端介绍150

6.2.1 词法分析和lex151

6.2.2 语法分析和yacc160

6.2.3 语义分析和IR生成介绍171

6.3 优化器介绍175

6.3.1 构造CFG176

6.3.2 分析和处理CFG181

6.3.3 数据流分析与SSA191

6.3.4 IR优化204

6.4 ART中的IR—HInstruction222

6.4.1 ART中的IR222

6.4.2 IR之间的关系225

6.4.3 ART IR对象的初始化231

6.5 寄存器分配233

6.5.1 LSRA介绍235

6.5.2 LSRA相关代码介绍247

6.6 机器码生成相关代码介绍271

6.6.1 GenerateFrameEntry272

6.6.2 VisitAdd和VisitInstance-FieldGet273

6.6.3 GenerateSlowPaths275

6.7 总结277

6.8 参考资料280

第7章 虚拟机的创建283

7.1 概述284

7.1.1 JniInvocation Init函数介绍286

7.1.2 AndroidRuntime startVm函数介绍287

7.2 Runtime Create介绍288

7.2.1 Create函数介绍288

7.2.2 Init函数介绍290

7.3 MemMap与OatFileManager293

7.3.1 MemMap介绍293

7.3.2 OatFileManager介绍298

7.4 FaultManager介绍302

7.4.1 信号处理和SignalAction介绍302

7.4.2 FaultManager介绍307

7.5 Thread介绍311

7.5.1 Startup函数介绍311

7.5.2 Attach函数介绍312

7.6 Heap学习之一325

7.6.1 初识Heap中的关键类326

7.6.2 Heap构造函数第一部分337

7.7 JavaVMExt和JNIEnvExt340

7.7.1 JavaVMExt341

7.7.2 JNIEnvExt343

7.7.3 总结344

7.8 ClassLinker345

7.8.1 关键类介绍345

7.8.2 ClassLinker构造函数352

7.8.3 InitFromBootImage353

7.8.4 ClassLinker总结360

7.9 总结和阅读指导362

第8章 虚拟机的启动363

8.1 Runtime Start364

8.2 初识JNI365

8.2.1 JNI中的数据类型365

8.2.2 ScopedObjectAccess等辅助类367

8.2.3 常用JNI函数介绍369

8.3 Jit LoadCompilerLibrary373

8.4 Runtime InitNativeMethods374

8.4.1 JniConstants Init374

8.4.2 RegisterRuntimeNative Methods375

8.4.3 WellKnownClasses Init和LastInit376

8.5 Thread相关376

8.5.1 Runtime InitThreadGroups377

8.5.2 Thread FinishSetup377

8.5.3 Runtime StartDaemonThreads380

8.6 Runtime CreateSystemClassLoader381

8.7 类的加载、链接和初始化383

8.7.1 关键类介绍383

8.7.2 SetupClass392

8.7.3 LoadClass相关函数393

8.7.4 LinkClass相关函数398

8.7.5 DefineClass414

8.7.6 Verify相关函数416

8.7.7 Initialize相关函数424

8.7.8 ClassLinker中其他常用函数426

8.7.9 ClassLoader介绍437

8.8 虚拟机创建和启动关键内容梳理445

第9章 深入理解dex2oat447

9.1 概述448

9.2 ParseArgs介绍452

9.2.1 CompilerOptions类介绍453

9.2.2 ProcessOptions函数介绍454

9.2.3 InsertCompileOptions函数介绍455

9.3 OpenFile介绍456

9.4 Setup介绍458

9.4.1 Setup代码分析之一458

9.4.2 Setup代码分析之二464

9.4.3 Setup代码分析之三474

9.4.4 Setup代码分析之四484

9.5 CompileImage484

9.5.1 Compile485

9.5.2 ArtCompileDEX496

9.5.3 OptimizingCompiler JniCompile499

9.5.4 OptimizingCompiler Compile527

9.6 OAT和ART文件格式介绍544

9.6.1 OAT文件格式544

9.6.2 ART文件格式550

9.6.3 oatdump介绍554

9.7 总结561

第10章 解释执行和JIT562

10.1 基础知识564

10.1.1 LinkCode564

10.1.2 Runtime ArtMethod566

10.1.3 栈和参数传递572

10.2 解释执行580

10.2.1 art_quick_to_interpreter_bridge580

10.2.2 artQuickToInterpreter-Bridge582

10.2.3 EnterInterpreterFromEntry-Point584

10.2.4 调用栈的管理和遍历593

10.3 ART中的JIT599

10.3.1 Jit、JitCodeCache等600

10.3.2 JIT阈值控制与处理609

10.3.3 OSR的处理612

10.4 HDeoptimize的处理615

10.4.1 VisitDeoptimize相关616

10.4.2 QuickExceptionHandler相关618

10.4.3 解释执行中关于Deoptimize的处理621

10.5 Instrumentation介绍623

10.5.1 MethodEnterEvent和MethodExitEvent624

10.5.2 DexPcMovedEvent625

10.6 异常投递和处理625

10.6.1 抛异常626

10.6.2 异常处理629

10.7 总结635

第11章 ART中的JNI636

11.1 JavaVM和JNIEnv637

11.1.1 JavaVMExt相关介绍638

11.1.2 JNIEnvExt介绍642

11.2 Java native方法的调用644

11.2.1 art_jni_dlsym_lookup_stub644

11.2.2 art_quick_generic_jni_trampoline646

11.3 CallStaticVoidMethod651

11.4 JNI中引用型对象的管理653

11.4.1 关键类介绍653

11.4.2 JniMethodStart和JniMethod-End657

11.4.3 IndirectReferenceTable相关函数658

11.4.4 NewObject和jobject的含义660

11.4.5 JNI中引用对象相关662

11.4.6 PushLocalFrame和PopLocalFrame663

11.4.7 回收引用对象664

11.5 总结666

第12章 CheckPoints、线程同步及信号处理668

12.1 CheckPoints介绍669

12.1.1 设置Check Point标志位670

12.1.2 Check Points的设置672

12.1.3 执行检查点处的任务676

12.2 ThreadList和ThreadState681

12.2.1 线程ID683

12.2.2 RunCheckpoint和Dump684

12.2.3 SuspendAll和ResumeAll687

12.2.4 Thread状态切换690

12.3 线程同步相关知识691

12.3.1 关键类介绍692

12.3.2 synchronized的处理697

12.3.3 Object wait、notifyAll等705

12.4 volatile成员的读写707

12.4.1 基础知识707

12.4.2 解释执行模式下的处理711

12.4.3 机器码执行模式的处理712

12.5 信号处理714

12.5.1 zygote进程的处理714

12.5.2 非zygote进程的处理716

12.6 总结719

第13章 内存分配与释放720

13.1 Space等关键类介绍722

13.2 ZygoteSpace723

13.3 BumpPointerSpace和RegionSpace725

13.3.1 BumpPointerSpace726

13.3.2 RegionSpace733

13.4 DlMallocSpace和RosAlloc-Space740

13.4.1 DlMallocSpace741

13.4.2 RosAllocSpace745

13.4.3 rosalloc介绍748

13.5 LargeObjectMapSpace760

13.6 new-instance/array指令的处理762

13.6.1 设置内存分配器762

13.6.2 解释执行模式下的处理767

13.6.3 机器码执行模式下的处理770

13.6.4 Heap AllocObjectWith-Allocator773

13.7 细观Space779

13.7.1 Space类779

13.7.2 ContinuousSpace和Discon-tinuousSpace类781

13.7.3 MemMapSpace和Continuous MemMapAllocSpace类782

13.7.4 MallocSpace类783

13.8 Heap学习之二784

13.8.1 Heap构造函数784

13.8.2 关键类介绍792

13.8.3 ObjectVisitReferences806

13.9 总结812

第14章 ART中的GC813

14.1 GC基础知识814

14.1.1 Mark-Sweep Collection原理介绍815

14.1.2 Copying Collection原理介绍817

14.1.3 Mark-Compact Collection原理介绍818

14.1.4 其他概念819

14.2 Runtime VisitRoots819

14.2.1 关键数据结构821

14.2.2 Thread VisitRoots824

14.3 ART GC概览827

14.3.1 关键数据结构827

14.3.2 ART GC选项830

14.3.3 创建回收器和设置回收策略832

14.4 MarkSweep835

14.4.1 Heap相关成员变量取值情况835

14.4.2 MarkSweep概貌837

14.4.3 MarkingPhase840

14.4.4 PausePhase848

14.4.5 ReclaimPhase851

14.4.6 FinishPhase857

14.4.7 PartialMarkSweep857

14.4.8 StickyMarkSweep858

14.4.9 Concurrent MarkSweep864

14.4.10 Parallel GC868

14.4.11 MarkSweep小结869

14.5 ConcurrentCopying870

14.5.1 InitalizePhase871

14.5.2 FlipThreadRoots873

14.5.3 MarkingPhase881

14.5.4 ReclaimPhase883

14.5.5ConcurrentCopying小结885

14.6 MarkCompact885

14.6.1 MarkingPhase886

14.6.2 ReclaimPhase889

14.6.3 MarkCompact小结891

14.7 SemiSpace892

14.7.1 InitializePhase893

14.7.2 MarkingPhase894

14.7.3 SemiSpace小结898

14.8 Java Reference对象的处理899

14.8.1 基础知识899

14.8.2 MarkSweep中Reference对象的处理903

14.8.3ReferenceProcessor904

14.8.4 PhantomReference的处理912

14.8.5 finalize函数的调用913

14.8.6 Reference处理小结917

14.9 Heap学习之三917

14.9.1 Heap Trim917

14.9.2 CollectGarbageInternal919

14.9.3 PreZygoteFork924

14.9.4 内存碎片的解决926

14.10 总结927

14.11 参考资料928


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。