📜  垃圾收集器如何在 Android 中工作?

📅  最后修改于: 2022-05-13 01:58:44.034000             🧑  作者: Mango

垃圾收集器如何在 Android 中工作?

首先,Dalvik 虚拟机上的垃圾回收通常比其他Java实现轻松得多,因为它不进行压缩。这表明堆上对象的地址在创建后永远不会改变,这使得 VM 实现的其余部分变得相当简单。因此,当代码中的某些分配失败时,垃圾收集器通常会被赋予清理任务,当出现以下这些情况时,可能会发生这种情况:

  1. OutOfMemoryError 即将被触发
  2. 当堆的尺寸达到某个预定义的软限制时,并且
  3. 当明确请求垃圾收集时。

这些原因中的每一个都有自己的规范,指示垃圾收集是否可能是部分垃圾收集(仅从活动堆中释放)、并发垃圾收集(在其他线程运行时做大部分事情标记)以及它是否是保留垃圾收集(保留软引用)。垃圾回收由日常场景中的软分配限制触发,仅在活动堆上释放、并发和保留。而在另一端,垃圾收集在极端内存不足异常完全同步之前触发!实际的垃圾收集是使用 Mark-Sweep 算法完成的。

标记扫描算法:它是如何工作的?

标记和清除算法是要开发主要垃圾拾取算法,可以回收循环数据结构。使用标记和清除时,未引用的对象不会立即回收。但是,与此不同的是,垃圾会一直累积,直到为该特定应用程序保留的所有内存都用完为止。当发生这样的事情时,软件的执行被暂停,并调用标记和清除算法来收集所有垃圾,在清除每个未引用的对象和元素后,执行又恢复正常!

标记和清除算法被称为跟踪垃圾人,因为它跟踪程序可以直接或间接访问的整个对象集合。程序可以直接访问的对象是那些被处理器堆栈上的局部变量引用的对象,也被任何询问对象的静态变量引用。在垃圾回收的上下文中,这些变量称为根。如果对象被另一个(直接或间接)可访问对象中的字段引用,则该对象是间接可访问的。一个可访问的对象声称是活的。相反,不存在的对象是垃圾。要解释标记和扫描算法,有两个阶段,我们需要先了解这两个阶段。它们是:

阶段1。 (又名标记阶段):指查找和标记所有可访问对象。

阶段2。 (又名清扫阶段):在此阶段,垃圾收集算法扫描堆并回收所有未标记的对象。

这是一个简短的图表,可帮助您完美理解各个阶段

(a) 描述 GC 启动前的情况

(b) 描述算法标记阶段的效果

(c) 描述扫描阶段完成后剩下的所有对象

在了解垃圾收集器的同时,还值得一提的是 Android 操作系统中的 GC 版本:

因此,Android OS 中有四个“版本”的 GC。

  1. Dalvik GC:主要的 GC 实现。这是一个严格的实现,也可以被认为是一种“停止世界”类型的实现。它停止 VM 中的所有线程并开始工作。
  2. ART GC 或 Generational GC (Lollipop & Marshmallow) :主要和最大的变化。 ART/Dalvik Android 团队重写了整个 GC。之所以这样称呼,是因为这些对象现在在它们存在的时候支持“世代”。
  3. ART GC牛轧糖):ART 电车现在在汇编级代码中修改了整个分配过程。
  4. ART GC (Oreo) : ART GC v1 的轻微改进。这被称为“并发复制垃圾收集器”

达尔维克?它是什么?

在 KitKat(4.4) 之前,Dalvik 一直是 Android 的当前运行时。但在 KitKat 中,它与臭名昭著的 ART 合并,这是软件巨头 Google 正在开发并与 Dalvik 并行发布的全新运行时,需要测试并从开发合作伙伴那里获得反馈。在 Lollipop 中,它已完全被 ART 取代。此时对象的分配和收集速度很慢。这是因为 Dalvik 中的垃圾收集器只是一个线程,即 Dalvik VM 暂停 VM 中的所有线程(所有系统线程、应用程序线程等)并触发 GC 以形成集合。因此,建议尽可能避免分配。

Dalvik 中的垃圾收集器使用前面提到的 Concurrent Mark and Sweep 算法。未引用的对象不会立即回收。相反,收集会延迟到所有可用内存都用完,这意味着短期对象在未使用后会在内存中保留更长的时间。您可以在此处了解有关 ART 的更多信息。

结束词

因此,正如您将看到的,在不同的 Android 版本中对收集器进行了大量更改。 ART 的引入及其新设计使 ART/Dalvik 团队能够提供改进,并且可以肯定的是,对平台本身进行了极好的改变。与 Dalvik 中的垃圾收集器相比,垃圾收集器已经发展成为一种增长更快、更成熟、更强大的 GC,允许更强大、更高效的分配方式和更细粒度的收集。它的锁定方式也得到了改进,只锁定需要收集的线程,而不是整个 VM。