2024年最全【Android进阶笔记】虚拟机(Dalvik、ART(1),社招面试心得

总结

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节

还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

一线互联网面试专题

379页的Android进阶知识大全

379页的Android进阶知识大全

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 对 CPU 资源敏感:在并发阶段,它虽然不会导致用户线程停顿,但会因为占用了一部分线程(或者说 CPU 资源)而导致应用程序变慢,总吞吐量会降低。
  • 无法处理浮动垃圾:在并发清除时,用户线程新产生的垃圾,称为浮动垃圾。

1.3. GC 日志

在 DVM 中每次垃圾收集都会将 GC 日志打印到 logcat 中,具体格式为: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

1.3.1. GC 原因

GC_Reason 指的是引起 GC 的原因,有以下几种。

  • GC_CONCURRENT:当堆开始填充时,并发 GC 可以释放内存。
  • GC_FOR_MALLOC:当堆内存已满时, App尝试分配内存而引起的 GC,系统必须停止 App 并回收内存。
  • GC_HPROF_DUMP_HEAP:当你请求创建 HPROF 文件来分析堆内存时出现的 GC。
  • GC_EXPLICIT:显式的 GC,例如调用 System.gc()(应该避免调用显式的 GC,信任 GC 会在需要时运行)。
  • GC_EXTERNAL_ALLOC:仅适用于 API 级别小于等于 10,且用于外部分配内存的 GC。

1.3.2. 其他字段

Amount_freed:本次 GC 释放内存的大小。

Heap_stats:堆的空闲内存百分比(已用内存 / 堆总内存)。

External_memory_stats:API 小于等于级别 10 的内存分配(已分配的内存 / 引起 GC 的阈值)。

Pause_time:暂停时间,堆越大暂停时间越长。并发暂停时间会显示两个,一个是垃圾收集开始时, 另一个是垃圾收集快要完成时。

1.3.3. 日志示例

D/dalvikvm: GC_CONCURRENT freed 2012K, 63% free 3213K/9291K, external 4501K/5161K, paused 2ms+2ms

本次 GC 原因是 GC_CONCURRENT;释放内存 2012KB;堆空闲内存占比 63%,已用3213KB,总内存为 9291KB;暂停总时长 4ms。


2. ART 虚拟机

ART(Android Runtime)虚拟机于 Android 4.4 发布,Android 5.0 中默认使用,用来代替 Dalvik 虚拟机。

2.1. 与 DVM 的区别

2.1.1. 运行机制区别

【DVM 基于 JIT 运行】

运行程序时使用解释器执行,同时将热点代码通过 JIT 编译器编译成机器码,并缓存到 jit code cache ,再执行时就无需解释直接运行。

【ART 基于 AOT 运行】

  • **Android 7.0 以前:**安装 APK 时把全部字节码进行 AOT 编译成机器码 .oat 文件,并存储到磁盘,程序运行时不需要编译直接使用。
  • **Android 7.0 开始:**安装 APK 时不进行全量编译,运行程序时使用解释器执行。
  • 将热点代码进行 JIT 编译成机器码,并缓存到 jit code cache,再执行时就无需解释直接运行。
  • 把经过 JIT 编译的热点方法记录到 Profile 配置文件中。
  • 当设备闲置和充电时,会启动编译守护进程,根据 Profile 文件把热点方法进行 AOT 编译成机器码 .oat 文件,并存储到磁盘待下次运行时直接使用。

2.1.2. CPU 区别

  • DVM 只支持 32位 CPU。
  • ART 支持 64位 CPU 并兼容 32位 CPU。

2.2. 解释器、JIT 和 AOT

实现 ART 即时 (JIT) 编译器

Java 为了实现“一次编写,随处运行”,将 java 代码编译成与本地平台无关的字节码文件,让字节码文件在不同平台、不同系统的不同虚拟机上运行,从而实现跨平台。而虚拟机运行字节码文件有多种不同方式:解释器JITAOT

2.2.1. 简介

  • **【解释器】:**解释器一次编译一行字节码并运行,实现成本低,性能低。
  • **【 JIT 】:**即时编译(Just-in-time)
  • 一次编译一个方法然后缓存到 jit code cache ,再次执行相同方法时就无需解释器编译,而直接运行,性能一般。
  • JIT 只会对经常执行的字节码(循环、高频方法)进行编译,以减少编译器负担。
  • 程序运行结束后,已编译并缓存的机器码将会被清除,下次运行会再次编译。
  • **【 AOT 】:**提前编译(Ahead-of-time)
  • 将全部字节码一次性编译成本地机器码,生成 .oat 文件并存储到磁盘空间,程序运行时不需要编译直接使用,性能好。
  • 由于会对全部字节码进行编译,因此安装 APK 时速度慢、安装之后占用的空间较大。

⭐️ **注意:**尽管 JIT 和 AOT 使用相同的编译器,且进行的一系列优化也较相似,但它们生成的代码可能会有所不同。JIT 会利用运行时类型信息,可以更高效地进行内联,并可让堆栈替换 (OSR) 编译成为可能,而这一切都会使其生成的代码略有不同。

2.2.2. 三者的配合

  • 已编译完成的机器码 .oat 文件,ART 虚拟机直接运行。
  • 未编译的字节码 .dex 文件,ART 虚拟机先判断是否热点代码:
  • 非热点代码:使用解释器解释运行。
  • 热点代码:使用 JIT 编译运行。

2.2.3. method 的编译运行

在 ART 中 ,执行一个方法前,可以在 ArtMethod 结构体中判断改方法是否已经被编译过了,从而使用不同的策略来执行方法。

当设备空闲且在充电时,AOT 编译守护程序(dex2oat)将解析 JIT 配置文件来编译热点方法。

  1. 唤醒并分析全部 APK。
  2. 判断该 app 是否被其他 app 所依赖使用:如果是,则全量编译该 apk 中的字节码,生成 .oat 文件。
  3. 否则判断对应的配置文件数据是否有意义:如果是,则根据配置文件中的描述,编译部分字节码,生成 .oat 文件。

2.3. 垃圾回收

不同版本,垃圾回收器不同,运行时堆也不同。而 ART 同时包含多种方案,OEM 厂商可以更改 GC 类型。

2.3.1. Android 8 之前

默认采用并发标记清除(CMS)方案。

支持内存压缩,但是有条件,进行的次数不多,可能会产生内存碎片。

  • 应用进入后台之前,它会避免执行压缩。
  • 应用进入后台之后,它会暂停应用线程以执行压缩(Stop-The-World)。
  • 如果对象分配因内存碎片而失败,则必须执行压缩操作,应用可能会短时间无响应。

2.3.2. Android 8 开始

默认采用并发复制(CC)方案。

  • 支持使用名为“RegionTLAB”的触碰指针分配器。此分配器可以向每个应用线程分配一个线程本地分配缓冲区 (TLAB),这样,应用线程只需触碰“栈顶”指针,而无需任何同步操作,即可从其 TLAB 中将对象分配出去。
  • 依靠读取屏障拦截来自堆的引用读取,并发复制对象来执行堆碎片整理,从而不用暂停用户线程。
  • GC 只有一次很短的暂停,对于堆大小而言,该次暂停在时间上是一个常量。

2.3.3. Android 10 开始

默认采用并发复制(CC)方案,但是增加了分代处理。

  • 支持快速回收存留期较短的对象,提高 GC 吞吐量,并降低全堆 GC 的执行。

2.4. GC 日志

ART 会在主动请求 GC 时或认为 GC 速度慢(暂停超过5ms或者持续超过100ms,且暂停可以被察觉)时才会打印 GC 日志,具体格式为:

<GC_Reason> <GC_Name> <Objects_freed>(<Size>) AllocSpace Objects, <Large_objects_freed>(<size>) <Heap_stats> LOS objects , <Pause_time> <Total_time>

2.4.1. GC 原因

GC_Reason 指的是引起 GC 的原因,有以下几种。

  • Concurrent:并发 GC,不会使 App 的线程暂停,该 GC 在后台线程运行,不会阻止内存分配。
  • Alloc:当堆内存已满时,App 尝试分配内存引起的 GC,这个 GC 会发生在正在分配内存的线程中。
  • Explicit:App显式的请求垃圾回收,例如调用 System.gc()
  • NativeAlloc:Native 内存分配时,触发的 GC。
  • CollectorTransition:由堆转换引起的回收,运行时切换 GC 引起的。将所有对象从空闲列表空间复制到碰撞指针空间,反之亦然。仅出现在内存较小的设备上App将进程从可察觉的暂停状态更改为可察觉的非暂停状态。
  • HomogeneousSpaceCompact:齐性空间压缩是指空闲列表到压缩的空闲列表空间,通常发生在App移动到可察觉的暂停进程状态。以此来减小内存使用并对堆内存进行碎片整理。
  • DisableMovingGc:不是真正触发 GC 的原因。发生并发堆压缩时,由于使用了GetPrimitiveArrayCritical,收集会被阻塞。
  • HeapTrim:不是触发 GC 的原因。收集会一直被阻塞,直到堆内存整理完毕。

2.4.2. 垃圾收集器名称

GC_Name 指的是垃圾收集器名称,有以下几种。

  • Concurrent Mark Sweep:CMS 收集器,采用标记清除算法实现,收集暂停时间短。完整的堆垃圾收集器,能释放除了 Image Space 外的所有空间。
  • Concurrent Partial Mark Sweep:局部收集器,能释放除了 Image Space 和 Zygote Space 外的所有空间。
  • Concurrent Sticky Mark Sweep:粘性收集器,基于分代的垃圾收集思想,只能释放自上次 GC 以来分配的对象。比完整或局部垃圾收集器扫描更频繁、更快且暂停时间更短。
  • Marksweep + Semispace:非并发的 GC,复制 GC 用于堆转换以及碎片整理。

2.4.3. 其他字段

  • Objects_freed:从非 Large Object Space 中回收的对象的数量。
  • Size_freed:从非 Large Object Space 中回收的字节数。
  • Large_objects_freed:从 Large O同ect Space 中回收的对象的数量。
  • Large_object_size_freed:从 Large Object Space 中回收的字节数。
  • Heap_stats:堆的空闲内存百分比,即(已用内存 / 堆的总内存)。
  • Pause_times:暂停时间,暂停时间与在 GC 运行时修改的对象引用的数量成比例。目前, ART 的 CMS 收集器仅有一次暂停,它出现在 GC 的结尾附近。移动的垃圾收集器暂停时间会很长,会在大部分垃圾回收期间持续出现 。

题外话

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升,故此将并将重要的Android进阶资料包括自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等学习资料。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

希望我能够用我的力量帮助更多迷茫、困惑的朋友们,帮助大家在IT道路上学习和发展~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值