内容简介:从Flutter technical-overview基本架构来说framework是使用最频繁的,但是对于engine和embedder确实flutter的底层,支持整个flutter的运行flutter 有三个学习层次,framework,engine,embedder 上层的framework负责ui相关的事情,动画,widget,绘图,手势,基础库 engine层次c++实现,支持flutter相关的渲染,线程管理,平台事件。engine里面有个内存泄漏,flutter官方一直没有解决,可以出门左转
从Flutter technical-overview基本架构来说framework是使用最频繁的,但是对于engine和embedder确实flutter的底层,支持整个flutter的运行
- 本文图片参考于闲鱼文章
- 架构图参考flutter.dev
flutter 有三个学习层次,framework,engine,embedder 上层的framework负责ui相关的事情,动画,widget,绘图,手势,基础库 engine层次c++实现,支持flutter相关的渲染,线程管理,平台事件。
engine里面有个内存泄漏,flutter官方一直没有解决,可以出门左转找到解决方案《手把手教你解决flutter内存泄漏》。一句话就是,flutter在处理flutter method channel和register与engine之间持有关系比较混乱,存在一个比较大的循环引用。
embedder 为engine提供四个task runner,将引擎移植到平台的中间层代码 渲染设置,原生插件,打包,线程管理,事件循环交互操作
在shell.cc里面可以看到,四个runner包括 ui runner gpu runner、io runner、platform runner
-
ui runner负责绑定渲染相关的操作,如通知engine有帧渲染,等待下一个vsync,对创建的widget进行layout并生成layer tree,更新layer tree信息,通知处理native plugin信息,如timer,microtask,异步io操作
-
gpu runner是用于执行gpu指令,负责将layer tree提供的信息转换为平台可执行的gpu指令,负责绘制gpu资源的管理,包括framebuffer,surface、texture、buffers
-
ios runner是处理图片数据,为gpu渲染做准备,比如读取磁盘压缩图片的格式,将解压成gpu能处理的格式,并传给gpu,因其比较消耗性能所以单独开一个线程。
-
platform runner,所有接口调用都使用该接口,长时间卡顿将会被watchdog强杀。
runner的实现策略,ios、android平台启动时为ui,gpu,io runner各自创建一个线程,但是共享platform runner和线程 Fushia,为ui,gpu,io,platform各自创建一个线程。
isolate 是dart vm自己管理,engine无法访问,它是对actor并发模式的实现,运行中程序由一个或多个actor组成,这些actor就是isolate。
原意是隔离的意思,表示没有共享内存和并发,逻辑上隔离,按顺序执行,不用担心死锁的问题。 isolate直接的通信方式只能通过port,消息传递异步,与普通线程最大的区别就是没有共享内存。 实现的步骤有,初始化isolate数据结构,初始化堆内存,进入对应所在的线程运行isolate,配置port,配置消息处理机制,配置debugger,将isolate注册到全局监控器。
与runner的关系,isolate是dart vm自己管理,engine无法访问。 如对于ui runner来说,isolate通过dart的c++调用能力,将ui渲染任务提交到ui runner,这样可以跟engine相关模块进行交互,ui相关的任务被提交到ui runner也给isolate一些事件通知,所以isolate同时处理app和native plugin的任务 对于gpu rnnner来说,isloate将dart的c++调用能力把gpu指令提交给gpu runner,把layer tree信息转换为gpu指令,这些都是通过isolate来执行的
分享一个坑,emmberdder里面有一个fml weakptr会造成四个task runner在reset的时候释放,但是不会把指针置空,会在一定几率下关闭flutterviewcontroller,造成崩溃,因为访问了野指针,fml的实现使用了uniqueptr智能指针,如果控制不好,这个应该后期会给flutter带来比较大的崩溃率。
测试代码
-(void)handleAutoRelase{ FlutterBasicMessageChannel* channel; FlutterEngine * engine; @autoreleasepool { FlutterViewController* flutterViewController = [[FlutterViewController alloc] init]; channel = flutterViewController.engine.systemChannel; engine = flutterViewController.engine; NSLog(@"engine111:%@",engine); } NSLog(@"engine222:%@",engine); [channel sendMessage:@"Hello!"]; [channel setMessageHandler:^(id _Nullable message, FlutterReply _Nonnull callback) { }]; } 复制代码
以上代码是google工程师提供的测试代码,autoreleasepool中包括了flutter和engine的创建,然后自动释放,然后在释放之后重新调用sendmessage的方法,此时会有一个访问野指针的崩溃。 对于engine的改写就需要放置在释放的时候放置对内部方法的访问
这样可以防止释放时候崩溃,但是对于根本的原因是fml内部实现的问题,如上所说,释放完成而指针变成了悬空指针。
engine的第二个隐患,在shell.cc访问weakptr一定会得到一个不为空的指针,即使是在engine或platformview释放的时候,以下是它的实现代码
粗略算了一下,四个taskrunner的getweakptr方法的实现都有隐患,归根到底还是fml的实现问题,悬空指针没有解决,这些都会造成野指针访问内存的崩溃。
- 本文 demo github.com/Natoto/flut…
- 【flutter engine 开发】QQ群号:217429001
以上所述就是小编给大家介绍的《flutter底层原理和embedder的隐忧》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 信通院专家:数据跨境流动的风险与隐忧
- AI繁荣下的隐忧——Google Tensorflow安全风险剖析
- avue 1.5.2 优化大量底层代码,crud 和 form 底层公用
- Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比
- Docker 底层原理浅析
- NSDictionary底层实现原理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C# 6.0本质论
[美] Mark Michaelis(马克·米凯利斯)、[美] Eric Lippert(埃里克·利珀特) / 周靖、庞燕 / 人民邮电出版社 / 2017-2-1 / 108
这是C#领域中一部广受好评的名作,作者用一种易于理解的方式详细介绍了C#语言的各个方面。全书共有21章和4个附录(其中哟2个附录从网上下载),介绍了C#语言的数据类型、操作符、方法、类、接口、异常处理等基本概念,深入讨论了泛型、迭代器、反射、线程和互操作性等高级主题,还介绍了LINQ技术,以及与其相关的扩展方法、分部方法、Lambda表达式、标准查询操作符和查询表达式等内容。每章开头的“思维导图”......一起来看看 《C# 6.0本质论》 这本书的介绍吧!