flutter底层原理和embedder的隐忧

栏目: IOS · 发布时间: 5年前

内容简介:从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底层原理和embedder的隐忧

flutter 有三个学习层次,framework,engine,embedder 上层的framework负责ui相关的事情,动画,widget,绘图,手势,基础库 engine层次c++实现,支持flutter相关的渲染,线程管理,平台事件。

engine里面有个内存泄漏,flutter官方一直没有解决,可以出门左转找到解决方案《手把手教你解决flutter内存泄漏》。一句话就是,flutter在处理flutter method channel和register与engine之间持有关系比较混乱,存在一个比较大的循环引用。

flutter底层原理和embedder的隐忧

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各自创建一个线程。

flutter底层原理和embedder的隐忧

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的改写就需要放置在释放的时候放置对内部方法的访问

flutter底层原理和embedder的隐忧

这样可以防止释放时候崩溃,但是对于根本的原因是fml内部实现的问题,如上所说,释放完成而指针变成了悬空指针。

engine的第二个隐患,在shell.cc访问weakptr一定会得到一个不为空的指针,即使是在engine或platformview释放的时候,以下是它的实现代码

flutter底层原理和embedder的隐忧
flutter底层原理和embedder的隐忧

粗略算了一下,四个taskrunner的getweakptr方法的实现都有隐患,归根到底还是fml的实现问题,悬空指针没有解决,这些都会造成野指针访问内存的崩溃。

flutter底层原理和embedder的隐忧

以上所述就是小编给大家介绍的《flutter底层原理和embedder的隐忧》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C# 6.0本质论

C# 6.0本质论

[美] Mark Michaelis(马克·米凯利斯)、[美] Eric Lippert(埃里克·利珀特) / 周靖、庞燕 / 人民邮电出版社 / 2017-2-1 / 108

这是C#领域中一部广受好评的名作,作者用一种易于理解的方式详细介绍了C#语言的各个方面。全书共有21章和4个附录(其中哟2个附录从网上下载),介绍了C#语言的数据类型、操作符、方法、类、接口、异常处理等基本概念,深入讨论了泛型、迭代器、反射、线程和互操作性等高级主题,还介绍了LINQ技术,以及与其相关的扩展方法、分部方法、Lambda表达式、标准查询操作符和查询表达式等内容。每章开头的“思维导图”......一起来看看 《C# 6.0本质论》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具