• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Dart内存管理机制

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Dart汇总请点击这里

Dart内存管理

Dart运行环境(VM)

和Android Art一样,Flutter也对Dart源码做了AOT编译,直接将Dart源码编译成了本地字节码,没有了解释执行的过程,提升执行性能。这里重点关注Dart VM内存分配(Allocate)和回收(GC)相关的部分。

和Java显著不同的是Dart的"线程"(Isolate)是不共享内存的,各自的堆(Heap)和栈(Stack)都是隔离的,并且是各自独立GC的,彼此之间通过消息通道来通信。Dart天然不存在数据竞争和变量状态同步的问题,整个Flutter Framework Widget的渲染过程都运行在一个isolate中。

Dart VM将内存管理分为新生代(New Generation)和老年代(Old Generation)。

新生代(New Generation)

通常初次分配的对象都位于新生代中,该区域主要是存放内存较小并且生命周期较短的对象,比如局部变量。新生代会频繁执行内存回收(GC),回收采用“复制-清除”算法,将内存分为两块(图中的from 和 to),运行时每次只使用其中的一块(图中的from),另一块备用(图中的to)。当发生GC时,将当前使用的内存块中存活的对象拷贝到备用内存块中,然后清除当前使用内存块,最后,交换两块内存的角色。

老年代(Old Generation)

在新生代的GC中“幸存”下来的对象,它们会被转移到老年代中。老年代存放生命力周期较长,内存较大的对象。老年代通常比新生代要大很多。老年代的GC回收采用“标记-清除”算法,分成标记和清除两个阶段。在标记阶段会触发停顿(stop the world),多线程并发的完成对垃圾对象的标记,降低标记阶段耗时。在清理阶段,由GC线程负责清理回收对象,和应用线程同时执行,不影响应用运行

可以看到,Dart VM借鉴了很多JVM的思路,Dart中产生内存泄露的方式也和Java类似,Java中很多排查内存泄露的思路和防止内存泄露的编程方法应该也可以借鉴过来

内存管理算法

GC(Garbage Collection),垃圾回收机制,简单地说就是程序中及时处理废弃不用的内存对象的机制,防止内存中废弃对象堆积过多造成内存泄漏

常见的垃圾回收算法有引用计数法(Reference Counting)、标注并清理(Mark and Sweep GC)、拷贝(Copying GC)和逐代回收(Generational GC)等算法。

iOS端

Objective-C语言本身是支持垃圾回收机制的,但有平台局限性,仅限于Mac桌面系统开发中,而在iPhone和iPad等苹果移动终端设备中是不支持垃圾回收机制的。在移动设备开发中的内存管理是采用MRC(Manual Reference Counting)以及iOS5以后的ARC(Automatic Reference Counting),本质都是RC引用计数,通过引用计数的方式来管理内存的分配与释放,从而防止内存泄漏。

iOS采用引用计数算法回收内存,当对象引用计数为0时,对象会执行反初始化方法并被回收。如果两个对象互相引用对方,就会造成循环强引用,导致内存泄漏。

Android端

Android系统采用的是标注并删除和拷贝GC,并不是大多数JVM实现里采用的逐代回收算法,根搜索算法回收内存,该算法通过GC Roots作为起点搜索,搜索通过的路径称为引用链,当一个对象没有被GC Roots的引用链连接的时候,这个对象就会被回收。即使A和B两个对象互相引用对方,只要A和B都不在引用链上,这两个对象都会被回收。

下图中的每个圆节点代表对象,箭头代表可达路径,当圆节点与 GC Roots 存在可达路径时,表示无法回收(黄色圆节点),反之则可以回收(蓝色圆节点)。

GC Root

  • 虚拟机栈(栈帧中的局部变量)中的引用的对象。
  • 方法区域中的类静态属性引用的对象。
  • 方法区域中常量引用的对象。
  • 本地方法栈中 JNI(Native 方法)的引用的对象。
  • 运行中线程引用的对象
GC与引用计数RC的区别

引用计数RC和垃圾回收GC是有区别的。

  • GC垃圾回收是宏观的,对整体进行内存管理,将所有对象看做一个集合,然后在GC循环中定时检测活动对象和非活动对象,及时将用不到的非活动对象释放掉来避免内存泄漏,也就是说用不到的垃圾对象是交给GC来管理释放的,而无需开发者关心,比如Java中的垃圾回收机制;
  • 引用计数是局部性的,开发者要管理控制每个对象的引用计数,单个对象引用计数为0后会马上被释放掉。ARC自动引用计数则是一种改进,由编译器帮助开发者自动管理控制引用计数(自动在合适的时机发送release和retain消息)。另外自动释放池autorelease pool则像是一个局部的垃圾回收,将部分垃圾对象集中释放,相对于单个释放会有一定延迟。
flutter

Flutter使用dart语言作为其开发语言和运行环境。dart的runtime是一直存在的,但是在debug和release模式下有一些区别。

在debug模式下,dart大部分组件都放在设备上,例如runtime、JIT(Android)、interpreter(iOS)、debug和profile services。

在release模式下,只剩下runtime,而这也是Flutter App能够运行起来的最基本组件。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap