欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

语言可以直接访问位元元址_OOP语言中FBC问题对应用框架的影响

发布时间:2025/3/21 编程问答 82 豆豆
生活随笔 收集整理的这篇文章主要介绍了 语言可以直接访问位元元址_OOP语言中FBC问题对应用框架的影响 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1,背景

FBI:fragile binary interface problem,是OOP编程语言的一个常见问题。

FBC:fragile base class,脆弱基类问题。

FBI在某种程度上等价FBC问题,但是比FBC意义更为广泛。这个地方我们用FBC来表示FBI。

// BaseClass is defined in a library class BaseClass {private:int a;int b;} // SubClass is defined in Application class SubClass :public BaseClass {private:int c;}

如果BaseClass里面增加一个新的成员变量,而App没有重新编译,App很容易会出现问题。对于编译器来说,访问一个成员变量基本就是:location(SubClass) + offset(c),如果BaseClass增加一个变量,原来应该访问c,其实同样的offset其含义已经变化了。处了成员变量,还有虚函数表等。If the author of the library changes the size or layout of the public fields within the object, the offsets are now invalid and the program will no longer work. This is the FBI problem. This leads to a problem in larger programs when they are constructed from libraries.

简单画了一个示意图,说明FBI问题在在一个开放的操作系统框架设计中重要性:App是通过应用市场发布的应用,如Android App;SDK API是操作系统提供的给应用开发者编程接口,如Android Framework接口。开放的操作系统要最大程度上保证OS版本的升级更新和应用的升级更新要相互独立,保证App程序最大兼容可用。

2,各种编程框架是如何处理FBI问题

既然FBI问题是所有OOP语言的共性问题,但是不同的编程语言及其编程语言的实现技术(静态编译/虚拟机)决定着FBI问题的严重程度,我们下来看看主流应用编程框架及其OS提供商是如何解决这个问题的。

2.1 Objective-C/IOS 框架

Objective-C是C语言衍生出来支持OOP的编程语言,使用LLVM工具链进行静态编译。静态编译会加重问题的发生,如上面例子看,静态编译成机器码,访问一个类的成员变量都是直接用的Offset。本身Apple设计人员是如何解决这个问题的:

编程语言/编译器层面:

1,Objective-C语言引入Non-fragile instance variables处理Field。Objective-C的编译器/Runtime会将对此种变量的访问都会变成间接访问,并且Runtime可以动态调整内存layout。https://opensource.apple.com/source/objc4/objc4-779.1/runtime/runtime.h.auto.html

2, Objective-C Method Dispatching机制:Clang编译器将所有对SuperClass的函数调用都转为对objc_msgSend(object, slector(message: ), param, nil)。当然Objective-C引入了一些标记static/@property(direct)避免每个method都使用dynamic dispatch。

框架层面:

  • 提供静态lib,来提升性能https://www.vadimbulavin.com/static-dynamic-frameworks-and-libraries/
  • 尽量保证API稳定性(下来找一下具体api变化数据)
  • 2.2 Swift/IOS 框架

    Swfit目前还没有提供语言层面解决FBC问题,目前IOS发布的Swift框架都是静态库发布,直接编译打包到App的bundle里面。Framewok和App一起编译,一起打包,一起运行,由于目前swift库非常小,静态库的方式还可以接受。Chris Lattner在Swift4中试图去解决这个问题:

    • 适应力(Resilience):这个功能提供了一种方式,在保证 ABI 稳定性同时,公有 API 可以随时间改进。一个例子,我们不想让 C++ 的“fragile base class” 问题发生在 Swift 中。更多设计与实现上的工作已经在 Swift 3 中完成了,但仍有重要工作未完成,包括模型中用户可见的部分(例如新的属性)。

    https://github.com/apple/swift/blob/master/docs/archive/Resilience.rst

    https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst

    Swift这几个文章是非常不错的,系统讨论如何保持高性能又可以解决FBC问题的方案,并且讨论了各个阶段保留语言抽象能力的问题(Compilation,Bundling,Installation,Loading,Execution),如果保持语言抽象能力在执行器,就需要增加很多metadata数据。

    2.3 Java,Kotlin/Android框架

    java/kotlin实现是被编译成了bytecode,bytecode相对机器指令保留了Loading/Execution语言抽象能力。对于bytecode虚拟机实现方式来说,FBC问题其实相对少很多,相对Swift来说不用考虑Class中因为增加field或者增加虚函数导致的FBC问题,因为虚拟机在Loading时候,才会把App Code和Framework Code进行Linking。因为语言实现JVM层面的友好性,只需要框架保证API接口的稳定和注意避免出现循环递归发生即可,OS可以灵活提供SDK。

    如果Java使用AOT编译技术变成机器指令,FBC问题就变的比较严重,Android系统提供给开发者的包是一个stub jar,只包括了对外接口的声明,用于编译,而真正的实现位于OS内部,编译器和运行器看到的代码是完全不同的。为了解决FBC问题,需要在编译器增加的metadata数据,runtime根据这些信息在Loading/Execution进行重算及其间接访问,带来极大的额外性能开销。由于Java支持动态ClassLoader特性,FBC问题变的更加严重,因为每个组件编译边界都需要增加这些额外的数据。Java AOT技术更适合close-world场景,应用和框架一起发布。

    2.4 Flutter等各种三方框架

    Flutter框架非OS系统自带的框架,因此FBC问题目前是被规避了。Flutter使用Dart,目前所有Dart代码和Runtime都会编译打包到App内部。因此Dart也是牺牲ROM来换取性能。

    最近看到Dart被选择为Fushia操作系统的应用开发语言,FBC问题会成为一个关键问题。除非Dart变成类似Jvm虚拟机执行方式或者Dart语言层面增加类似Swift的语言上FBC问题的支持。

    https://github.com/dart-lang/sdk/issues/520

    3. 给操作系统设计者的启示

    目前解决FBC问题有很多方法,处了通过编程语言增加特性及其编译器和runtime支持进行解决,还可以通过定义一些编程约束来避免FBC问题,如C++ Piml设计模式或者微软的COM组件模型。但是我个人认为增加编程约束或者规则给应用开发人员带来非常大的学习成本,并不是未来的发展趋势。

    1,FBC问题是Performance,Code Size,动态性及其开发效率的折衷。

    swift4的文章讨论来这个问题,在各个阶段保留语言抽象能力的问题(Compilation,Compilation,Installation,Loading,Execution)有利有弊。如C++语言仅在Compilation保留来语言抽象能力,好处在于可以通过编译器做最大程度的优化,也不需要增加对SuperClass Field访问增加间接访问,但是FBC问题更为严重,只能定义编程规则避免FBC问题,给开发者带来额外的开发学习成本和维护工作量。对于Java来说保留了一定的语言抽象能力到Loading/Execution,但是会增加Loading时间,并且在端侧设备上编译优化算法由于算力会受到限制(WPO等)并且当classload新加载一个jar的时候,为了支持classloader语义,需要退化为解释器,jit和aot都需要重新计算。

    • Loading Time
    • The direct cost of many small added indirections
    • code-size inflation due to the extra logic to implement these operations
    • diminished potential for more powerful optimizations such as inlining and code motion

    2,FBC对于一个开放生态OS应用编程语言的设计是需要认真考虑的一个问题

    应用编程语言FBC必须好好考虑,如Swift一样,如果在Performance和语言灵活性上取得平衡。

    3,选择什么样的编程语言给应用开发者?

    我个人更喜欢FBC友好的语言,例如java,js这些语言,给OS和应用开发者都更加友好,OS可以提供更加灵活的SDK发布形式,对于应用开发者也不需要为FBC问题需要学习很多编程约束。同时这些语言往往支持动态加载,给应用的架构带来更多的灵活性。

    4,选择什么样的开发框架API的发布方式?

    具体选择使用动态库还是静态库,取决于API稳定性,针对已经稳定的API可以选择动态库发布,对于未稳定的版本对于FBC敏感的语言可以优先发布静态库。

    参考:

    https://en.wikipedia.org/wiki/Fragile_binary_interface_problem

    https://developer.apple.com/documentation/swift/swift_standard_library/

    http://user.engineering.uiowa.edu/~kuhl/CompSoft/Slides2011/The%20Fragile%20Base%20Class%20Problem.pdf

    Objective-C Direct Methods

    《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

    总结

    以上是生活随笔为你收集整理的语言可以直接访问位元元址_OOP语言中FBC问题对应用框架的影响的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。