语言可以直接访问位元元址_OOP语言中FBC问题对应用框架的影响
1,背景
FBI:fragile binary interface problem,是OOP編程語(yǔ)言的一個(gè)常見(jiàn)問(wèn)題。
FBC:fragile base class,脆弱基類問(wèn)題。
FBI在某種程度上等價(jià)FBC問(wèn)題,但是比FBC意義更為廣泛。這個(gè)地方我們用FBC來(lái)表示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里面增加一個(gè)新的成員變量,而App沒(méi)有重新編譯,App很容易會(huì)出現(xiàn)問(wèn)題。對(duì)于編譯器來(lái)說(shuō),訪問(wèn)一個(gè)成員變量基本就是:location(SubClass) + offset(c),如果BaseClass增加一個(gè)變量,原來(lái)應(yīng)該訪問(wèn)c,其實(shí)同樣的offset其含義已經(jīng)變化了。處了成員變量,還有虛函數(shù)表等。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.
簡(jiǎn)單畫(huà)了一個(gè)示意圖,說(shuō)明FBI問(wèn)題在在一個(gè)開(kāi)放的操作系統(tǒng)框架設(shè)計(jì)中重要性:App是通過(guò)應(yīng)用市場(chǎng)發(fā)布的應(yīng)用,如Android App;SDK API是操作系統(tǒng)提供的給應(yīng)用開(kāi)發(fā)者編程接口,如Android Framework接口。開(kāi)放的操作系統(tǒng)要最大程度上保證OS版本的升級(jí)更新和應(yīng)用的升級(jí)更新要相互獨(dú)立,保證App程序最大兼容可用。
2,各種編程框架是如何處理FBI問(wèn)題
既然FBI問(wèn)題是所有OOP語(yǔ)言的共性問(wèn)題,但是不同的編程語(yǔ)言及其編程語(yǔ)言的實(shí)現(xiàn)技術(shù)(靜態(tài)編譯/虛擬機(jī))決定著FBI問(wèn)題的嚴(yán)重程度,我們下來(lái)看看主流應(yīng)用編程框架及其OS提供商是如何解決這個(gè)問(wèn)題的。
2.1 Objective-C/IOS 框架
Objective-C是C語(yǔ)言衍生出來(lái)支持OOP的編程語(yǔ)言,使用LLVM工具鏈進(jìn)行靜態(tài)編譯。靜態(tài)編譯會(huì)加重問(wèn)題的發(fā)生,如上面例子看,靜態(tài)編譯成機(jī)器碼,訪問(wèn)一個(gè)類的成員變量都是直接用的Offset。本身Apple設(shè)計(jì)人員是如何解決這個(gè)問(wèn)題的:
編程語(yǔ)言/編譯器層面:
1,Objective-C語(yǔ)言引入Non-fragile instance variables處理Field。Objective-C的編譯器/Runtime會(huì)將對(duì)此種變量的訪問(wèn)都會(huì)變成間接訪問(wèn),并且Runtime可以動(dòng)態(tài)調(diào)整內(nèi)存layout。https://opensource.apple.com/source/objc4/objc4-779.1/runtime/runtime.h.auto.html
2, Objective-C Method Dispatching機(jī)制:Clang編譯器將所有對(duì)SuperClass的函數(shù)調(diào)用都轉(zhuǎn)為對(duì)objc_msgSend(object, slector(message: ), param, nil)。當(dāng)然Objective-C引入了一些標(biāo)記static/@property(direct)避免每個(gè)method都使用dynamic dispatch。
框架層面:
2.2 Swift/IOS 框架
Swfit目前還沒(méi)有提供語(yǔ)言層面解決FBC問(wèn)題,目前IOS發(fā)布的Swift框架都是靜態(tài)庫(kù)發(fā)布,直接編譯打包到App的bundle里面。Framewok和App一起編譯,一起打包,一起運(yùn)行,由于目前swift庫(kù)非常小,靜態(tài)庫(kù)的方式還可以接受。Chris Lattner在Swift4中試圖去解決這個(gè)問(wèn)題:
- 適應(yīng)力(Resilience):這個(gè)功能提供了一種方式,在保證 ABI 穩(wěn)定性同時(shí),公有 API 可以隨時(shí)間改進(jìn)。一個(gè)例子,我們不想讓 C++ 的“fragile base class” 問(wèn)題發(fā)生在 Swift 中。更多設(shè)計(jì)與實(shí)現(xiàn)上的工作已經(jīng)在 Swift 3 中完成了,但仍有重要工作未完成,包括模型中用戶可見(jiàn)的部分(例如新的屬性)。
https://github.com/apple/swift/blob/master/docs/archive/Resilience.rst
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst
Swift這幾個(gè)文章是非常不錯(cuò)的,系統(tǒng)討論如何保持高性能又可以解決FBC問(wèn)題的方案,并且討論了各個(gè)階段保留語(yǔ)言抽象能力的問(wèn)題(Compilation,Bundling,Installation,Loading,Execution),如果保持語(yǔ)言抽象能力在執(zhí)行器,就需要增加很多metadata數(shù)據(jù)。
2.3 Java,Kotlin/Android框架
java/kotlin實(shí)現(xiàn)是被編譯成了bytecode,bytecode相對(duì)機(jī)器指令保留了Loading/Execution語(yǔ)言抽象能力。對(duì)于bytecode虛擬機(jī)實(shí)現(xiàn)方式來(lái)說(shuō),FBC問(wèn)題其實(shí)相對(duì)少很多,相對(duì)Swift來(lái)說(shuō)不用考慮Class中因?yàn)樵黾觙ield或者增加虛函數(shù)導(dǎo)致的FBC問(wèn)題,因?yàn)樘摂M機(jī)在Loading時(shí)候,才會(huì)把App Code和Framework Code進(jìn)行Linking。因?yàn)檎Z(yǔ)言實(shí)現(xiàn)JVM層面的友好性,只需要框架保證API接口的穩(wěn)定和注意避免出現(xiàn)循環(huán)遞歸發(fā)生即可,OS可以靈活提供SDK。
如果Java使用AOT編譯技術(shù)變成機(jī)器指令,FBC問(wèn)題就變的比較嚴(yán)重,Android系統(tǒng)提供給開(kāi)發(fā)者的包是一個(gè)stub jar,只包括了對(duì)外接口的聲明,用于編譯,而真正的實(shí)現(xiàn)位于OS內(nèi)部,編譯器和運(yùn)行器看到的代碼是完全不同的。為了解決FBC問(wèn)題,需要在編譯器增加的metadata數(shù)據(jù),runtime根據(jù)這些信息在Loading/Execution進(jìn)行重算及其間接訪問(wèn),帶來(lái)極大的額外性能開(kāi)銷(xiāo)。由于Java支持動(dòng)態(tài)ClassLoader特性,FBC問(wèn)題變的更加嚴(yán)重,因?yàn)槊總€(gè)組件編譯邊界都需要增加這些額外的數(shù)據(jù)。Java AOT技術(shù)更適合close-world場(chǎng)景,應(yīng)用和框架一起發(fā)布。
2.4 Flutter等各種三方框架
Flutter框架非OS系統(tǒng)自帶的框架,因此FBC問(wèn)題目前是被規(guī)避了。Flutter使用Dart,目前所有Dart代碼和Runtime都會(huì)編譯打包到App內(nèi)部。因此Dart也是犧牲ROM來(lái)?yè)Q取性能。
最近看到Dart被選擇為Fushia操作系統(tǒng)的應(yīng)用開(kāi)發(fā)語(yǔ)言,FBC問(wèn)題會(huì)成為一個(gè)關(guān)鍵問(wèn)題。除非Dart變成類似Jvm虛擬機(jī)執(zhí)行方式或者Dart語(yǔ)言層面增加類似Swift的語(yǔ)言上FBC問(wèn)題的支持。
https://github.com/dart-lang/sdk/issues/520
3. 給操作系統(tǒng)設(shè)計(jì)者的啟示
目前解決FBC問(wèn)題有很多方法,處了通過(guò)編程語(yǔ)言增加特性及其編譯器和runtime支持進(jìn)行解決,還可以通過(guò)定義一些編程約束來(lái)避免FBC問(wèn)題,如C++ Piml設(shè)計(jì)模式或者微軟的COM組件模型。但是我個(gè)人認(rèn)為增加編程約束或者規(guī)則給應(yīng)用開(kāi)發(fā)人員帶來(lái)非常大的學(xué)習(xí)成本,并不是未來(lái)的發(fā)展趨勢(shì)。
1,FBC問(wèn)題是Performance,Code Size,動(dòng)態(tài)性及其開(kāi)發(fā)效率的折衷。
swift4的文章討論來(lái)這個(gè)問(wèn)題,在各個(gè)階段保留語(yǔ)言抽象能力的問(wèn)題(Compilation,Compilation,Installation,Loading,Execution)有利有弊。如C++語(yǔ)言僅在Compilation保留來(lái)語(yǔ)言抽象能力,好處在于可以通過(guò)編譯器做最大程度的優(yōu)化,也不需要增加對(duì)SuperClass Field訪問(wèn)增加間接訪問(wèn),但是FBC問(wèn)題更為嚴(yán)重,只能定義編程規(guī)則避免FBC問(wèn)題,給開(kāi)發(fā)者帶來(lái)額外的開(kāi)發(fā)學(xué)習(xí)成本和維護(hù)工作量。對(duì)于Java來(lái)說(shuō)保留了一定的語(yǔ)言抽象能力到Loading/Execution,但是會(huì)增加Loading時(shí)間,并且在端側(cè)設(shè)備上編譯優(yōu)化算法由于算力會(huì)受到限制(WPO等)并且當(dāng)classload新加載一個(gè)jar的時(shí)候,為了支持classloader語(yǔ)義,需要退化為解釋器,jit和aot都需要重新計(jì)算。
- 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對(duì)于一個(gè)開(kāi)放生態(tài)OS應(yīng)用編程語(yǔ)言的設(shè)計(jì)是需要認(rèn)真考慮的一個(gè)問(wèn)題
應(yīng)用編程語(yǔ)言FBC必須好好考慮,如Swift一樣,如果在Performance和語(yǔ)言靈活性上取得平衡。
3,選擇什么樣的編程語(yǔ)言給應(yīng)用開(kāi)發(fā)者?
我個(gè)人更喜歡FBC友好的語(yǔ)言,例如java,js這些語(yǔ)言,給OS和應(yīng)用開(kāi)發(fā)者都更加友好,OS可以提供更加靈活的SDK發(fā)布形式,對(duì)于應(yīng)用開(kāi)發(fā)者也不需要為FBC問(wèn)題需要學(xué)習(xí)很多編程約束。同時(shí)這些語(yǔ)言往往支持動(dòng)態(tài)加載,給應(yīng)用的架構(gòu)帶來(lái)更多的靈活性。
4,選擇什么樣的開(kāi)發(fā)框架API的發(fā)布方式?
具體選擇使用動(dòng)態(tài)庫(kù)還是靜態(tài)庫(kù),取決于API穩(wěn)定性,針對(duì)已經(jīng)穩(wěn)定的API可以選擇動(dòng)態(tài)庫(kù)發(fā)布,對(duì)于未穩(wěn)定的版本對(duì)于FBC敏感的語(yǔ)言可以優(yōu)先發(fā)布靜態(tài)庫(kù)。
參考:
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
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的语言可以直接访问位元元址_OOP语言中FBC问题对应用框架的影响的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sensor曝光量和曝光行的区别_4个要
- 下一篇: elk 搜索 语法_ELK从入门到还未精