Flutter中的垃圾回收机制

1.介绍

Flutter主要使用Dart开发语言,在调试和发布两个版本中,Dart RunTime是始终存在,但两种版本下的构建方式有很大的差异

2.调试和发布版本下的差异

  • 调试版本下
    Dart编译到设备,包含三部分:
    1.Dart RunTime
    2.jit(Android下的实时编译器)/interpreter(IOS下的解析器)
    3.调试和分析服务

  • 发布版本下
    1.Dart RunTime

两种模式下都存在Dart RunTime,它包含了垃圾收集器,是实例化对象并变得无法访问时分配和释放内存的必要组件。

3.垃圾收集器竞技场

对于Flutter而言,会创建很多对象:例如Stateless Widget从创建到应用程序的状态发生改变或者变得不再可见时被销毁和重建,大多数对象的生命周期是短暂的,若应用程序的UI变得相对复杂,可运行至上千个小部件

对于上面而言,很多人之前认为Flutter为什么不用Java写,为什么不用Object-C写,为什么不用JavaScript写,对于这些语言真的能胜任这么频繁的创建销毁吗?

  • Java垃圾收集器

    • jvm中java的内存分为四个部分:
      1.Java栈:主要作用存放方法执行的时候所有的数据,由栈帧代表一个方法的执行,每个方法从调用到执行完成在虚拟机为一个栈帧的入栈和出栈,栈帧的信息包括局部变量表,栈操作数,动态链接,方法出口
      2.本地方法栈:主要为native服务,例如C、C++方法
      3.方法区:存储被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的数据等
      4.堆区:所有通过new创建的对象的内存都在堆中分配,堆内存分为新的和旧的,刚new出来的对象放在新生代存储,当内存不足时,虚拟机会通过一系列算法把新生对象移动到旧生代中去

    • 注意:
      1.当方法栈深度大于JVM深度的时候,就会栈溢出,例如:死循环(stackOverflow)
      2.新生代和旧生代都满了,就会导致内存溢出(OutOfMemory)

    • 垃圾收集器的算法
      垃圾回收主要针对堆内存,算法主要包括垃圾的确定与收集、垃圾的回收、垃圾的回收时机
      1.引用计数法(废弃):若对象被引用就会+1,没有被引用的时候就回收,但引用计数法无法解决对象之间相互调用的问题
      2.可达性算法:通过gc root对象开始搜索,不可达的对象会被回收,引用的类型主要有强引用、弱引用,当存在强引用时宁愿抛出oom也不回收、但是弱引用的话,有可能被回收。
      3.标记清除法:搜索发现没有引用的对象直接回收,但是导致碎片过多
      4.复制算法:搜索扫描没有引用的对象,开辟新的内存空间,将存活的对象复制到新的内存,旧的内存直接删除,由于交换空间,适合对象比较少的时候,并且内存空间缩短一半
      5.标记整理法:在标记清除法的基础上,清除掉不存活的对象,把后面存活的对象挪动过来,解决碎片问题

    • 上面的垃圾收集器算法在jvm中没有明确的规范,由各个厂商去实现

  • Object-C垃圾收集器

OC在早期版本中缺少较为完善的内存管理机制,需要开发者手动进行释放,在Xcode4.2之后引入了ARC(Automatic Reference Counting)机制。

  • ARC机制
    ARC叫做自动引用计数,ARC中常见的所有权关键字:

    • assign 对应关键字__unsafe_unretained,指向的对象被释放的时候,仍然指向之前的地址,容易引起野指针
    • copy 对应关键字__strong,在赋值的时候,调用copy方法
    • retain 对应关键字__strong
    • strong 对应关键字__strong
    • unsafe_unretained 对应关键字unsafe_unretained
    • weak 对应关键字weak
  • ARC内部实现
    ARC背后的引用计数主要依赖于三个方法:

    • retain 增加引用计数
    • release 降低引用计数,当引用计数为0时释放对象
    • autorelease 在当前的auto release pool结束后,降低引用计数
  • JavaScript垃圾收集器

javaScript 具有垃圾自动收集机制,垃圾收集器会按照固定的时间间隔,周期性地执行这一炒作,具体到浏览器的实现,也可以指定收集时间

  • 垃圾收集的方法

    • 标记清除法 javaScript中最重要的收集方法,给当前不使用的值加上标记,然后等待回收其内存
    • 引用计数(不再使用) 跟踪记录每个值被引用的次数,当声明了一个变量,并将一个引用类型赋值给该变量之后,引用次数加1,跟java一样
    • 性能问题 垃圾收集器是周期运行的,而且如果变量分配的内存数量比较大,那么回收工作量也是相当的大
  • Dart垃圾收集器

Dart的垃圾收集器是分代的,由两个部分组成:新生代空间收集器、并行标记扫描收集器,还有一个重要的东西,就是调度器

  • 调度器
    在Flutter引擎中,为了最小化垃圾收集对应用程序和UI性能的印象,与垃圾收集器提供了hook,当引擎检测到应用程序处于空闲状态(没有与用户交互)会发出警报,为垃圾收集器提供运行其收集阶段而不影响性能的机会。并且垃圾收集器可以在这些空闲时间运行内存压缩,从而较少内存碎片来优化内存
  • 新生代空间收集器
    此部分类似于Java的复制算法,用于清理寿命较短的对象,例如Stateless部件,虽然是会阻塞线程,但当与调度器结合使用,几乎感知不到应用程序在运行期间的暂停,从本质上,新建的对象被分配给内存中的连续空间,在新建对象,会被分配到下一个可用空间,直到填充完分配的内存,但Dart使用的是一个凹凸的指针,所以这个过程非常快,分配新对象的空间由两部分组成,任何时候只用一半,当一半满后,活动的对象将复制到另一半空间中,一半就会全部清空,确定对象是否活动,收集器以根对象开始,进行检测他们引用的内容,这一部分类似于Java的可达性算法,有引用的对象将会被复制到另一个空间中
  • 并行标记扫描收集器
    当对象达到一定的生命周期时,会被提上到另一个新的内存空间,由另一个收集器管理,此收集器有两个阶段:
    • 遍历对象,标记仍在使用的对象
    • 扫描整个存储器,并回收未标记的对象,然后清除所有标记

4.总结

由上面所述,Dart的垃圾收集器方式参考了部分语言的实现,但需要注意的是,Dart的isolates拥有自己的私有堆,彼此是独立的,每个isolates运行在单独的线程中,每个ioslates的垃圾收集事件不影响其它isolates的性能,所以isolates可以避免UI出现卡顿和很好的进行频繁的回收操作,这就是dart作为Flutter的主要语言的原因之一。

参考:
1.Flutter: Don’t Fear the Garbage Collector

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352