Flutter以使用Dart语言为主,其内存管理机制与Java有一定的相似性,Dart中有一个垃圾收集器的概念,
Dart的垃圾收集器是分代的(新生代(New Generation)和老年代(Old Generation)),由两个部分组成:
1.新生代空间收集器
2.并行标记扫描收集器
新生代用来存储生命周期较短的对象,由两个内存空间组成,Active内存空间用来分配新对象,inActive内存空间用来作为备用空间,DartVM的内存分配策略非常简单,创建对象时只需要在现有堆上移动指针,内存增长始终是线形的,省去了查找可用内存段的过程。每个Isolate有自己独立的Heap,相互之间无法共享内存,这样可以实现无锁的快速分配。
一旦Active的内存空间被填满,垃圾回收器会从根对象开始遍历检查检查所有对象的引用状态,没有被引用的对象标记为dead状态,非dead状态的对象在下次内存回收事件中会被复制到inActive内存空间,清除Active内存空间,最后Active和inActive内存空间状态调换。
另外还有调度器
由这三个部分组成了垃圾收集器
调度器
在Flutter引擎中,为了最小化垃圾收集对应用程序和UI性能的印象,与垃圾收集器提供了hook,当引擎检测到应用程序处于空闲状态(没有与用户交互),会发出警报,为垃圾收集器提供运行其收集阶段而不影响性能的机会。并且垃圾收集器可以在这些空闲时间运行内存压缩,从而较少内存碎片来优化内存。
从以下flutter - iOS程序内存情况中可以明显的看出在1处没有用户交互的情况下Flutter引擎中的垃圾收集器开始工作,稍候在2处内存有明显释放的痕迹。
新生代空间收集器
此部分类似于Java的复制算法,用于清理寿命较短的对象,例如Stateless部件,虽然是会阻塞线程,但当与调度器结合使用,几乎感知不到应用程序在运行期间的暂停,从本质上,新建的对象被分配给内存中的连续空间,在新建对象,会被分配到下一个可用空间,直到填充完分配的内存,但Dart使用的是一个凹凸的指针,所以这个过程非常快,分配新对象的空间由两部分组成,任何时候只用一半,当一半满后,活动的对象将复制到另一半空间中,一半就会全部清空,确定对象是否活动,收集器以根对象开始,进行检测他们引用的内容,这一部分类似于Java的可达性算法,有引用的对象将会被复制到另一个空间中。
并行标记扫描收集器
当对象达到一定的生命周期时,会被提上到另一个新的内存空间,由另一个收集器管理,此收集器有两个阶段:
遍历对象,标记仍在使用的对象
扫描整个存储器,并回收未标记的对象,然后清除所有标记。
网友评论