週末在家休息,女友在刷朋友圈,忽然她問我:算法
2019年8月9日華爲開發者大會上,華爲消費者業務CEO餘承東正式宣佈發佈自有操做系統鴻蒙,內核爲Linux內核、鴻蒙微內核和LiteOS。將來將擺脫Linux內核和LiteOS,只有鴻蒙微內核。編程
鴻蒙(英語:Harmony OS,開發代號Ark)是華爲自2012年開發的一款可能兼容Android app的跨平臺操做系統。安全
在之前,平臺 ≈ 操做系統
。因此,傳統意義上的跨平臺即不依賴於操做系統,也不依賴硬件環境。一個操做系統下開發的應用,放到另外一個操做系統下依然能夠運行。markdown
可是隨着科技的發展,平臺 ≈ 操做系統
已經不成立了,就像華爲推出的鴻蒙OS,他能夠支持到多種多樣的設備,如手機、手錶、電腦、汽車、智能家居設備等。網絡
因此,今天咱們談的跨平臺,指的是跨設備。即平臺 ≈ 設備
架構
因此,華爲但願鴻蒙OS能夠運行在各類各樣的設備上,因此,鴻蒙OS必然須要具有跨平臺的能力。app
並且,鴻蒙想要作的不只僅是操做系統能夠跨平臺,更重要的是要讓用戶和開發者真正的感覺到跨平臺。分佈式
因此,跨平臺操做系統鴻蒙的目的是:使開發者可以聚焦自身業務邏輯,像開發同一終端同樣開發跨終端分佈式應用,也使最終消費者享受到強大的跨終端業務協同能力爲各使用場景帶來的無縫體驗。佈局
先來講說Java是如何實現跨平臺的。post
Java對於跨平臺的支持,就像對安全性和網絡移動性的支持同樣,是分佈在整個Java體系結構中的。其中扮演者重要的角色的有Java語言規範、Class文件、Java虛擬機(JVM)等。
首先,在Java語言規範中,規定了Java語言中基本數據類型的取值範圍和行爲。其次,全部Java文件要編譯成統一的Class文件。最後,經過Java虛擬機將Class文件轉成對應平臺的二進制文件。
Java的平臺無關性是創建在Java虛擬機的平臺有關性基礎之上的,是由於Java虛擬機屏蔽了底層操做系統和硬件的差別。
想要運行一段Java代碼,要通過多個步驟,將Java源代碼轉換成機器能夠執行的機器代碼,這個過程主要由虛擬機來完成。
在著名的HotSpot虛擬機中,主要有解釋執行和即時編譯兩種形式:
解釋執行
逐條將字節碼翻譯成機器碼並執行
即時編譯(Just-in-time ,JIT)
將一個方法中包含的全部字節碼編譯成機器碼後再執行。
HotSpot 默認採用混合模式,綜合瞭解釋執行和即時編譯二者的優勢。它會先解釋執行字節碼,然後將其中反覆執行的熱點代碼(熱點檢測),以方法爲單位進行即時編譯。
Android其實基於Java語言的,因此同理,想要運行一段Android代碼,也要通過多個步驟,將Android源代碼轉換成機器能夠執行的機器代碼。
可是這個轉換過程在Android的不一樣版本中實現不盡相同:
Android 1.0(2008 年):採用一個名爲 Dalvik 的虛擬機,而且集成了一個解釋器。當 App 運行時,就會調用這個解釋器,對代碼進行逐句解釋,速度很慢。
Android 2.2(2010 年):引入 JIT(Just In Time)即時編譯機制,當 App 運行時,會將用戶常用的功能編譯爲機器能直接執行的 010101 機器碼,不用一句一句地去翻譯。當出現不經常使用的功能時,再調用解釋器來翻譯;這樣速度加快,但每次啓動 App 都要從新編譯一次,不能一勞永逸。
Android 5.0(2014 年 10 月):將虛擬機 Dalvik 換成 ART(Android Run Time),將 JIT 的編譯器替換成 AOT(Ahead of Time)。如此,App 在下載後安裝到手機上時同時把能編譯的代碼先編譯成機器聽得懂的 101010;剩下不太好翻譯的代碼,就在用戶使用時再叫醒解釋器來翻譯。如此,不用每次打開 App 都須要編譯,但安裝 App 的時間有點長,並且佔用手機空間。
Android 7.0(2016 年):採用混合編譯機制,安裝時先不編譯中間代碼,而是在用戶空閒時將可以編譯成機器碼的那部分代碼,經過 AOT 編譯器先靜態編譯了。若是 AOT 還沒來得及編譯或者不能編譯,再調用 JIT+ 解釋器。這種機制,至關於用時間換空間,既縮短了用戶安裝 APP 的等待時間,又將虛擬機裏編譯器和解釋器能作的優化提高到最大效率了。
能夠看到,從2008年的Android 1.0開始,Android在編譯優化上面在一直下功夫。
當前的 Android 採用的是解釋執行 + JIT + AOT 的綜合模式,在 空間佔用+安裝速度+運行速度 上已經達到了一個很好的平衡。
可是Android的編譯問題一直被詬病。儘管在後續的Android 8.0 上改進了解釋器,解釋模式執行效率大幅提高;Android 10.0 上提供了預先放置熱點代碼的方式,應用在安裝的時候就能知道經常使用代碼會被提早編譯。
可是,目前來看,不管如何,Android都沒能擺脫這樣一個前提:即應用在被打包成 APK 的時候,採用的仍是 Java 代碼。換句話說,在 APK 變成用戶可應用的過程當中,還經歷了一個在 Android 系統內部的編譯過程,這是一個繞不過的坎。
那麼,鴻蒙OS的代碼編譯是怎麼樣的呢?他又是如何解決跨平臺的問題的呢?
從上圖中能夠看到,在鴻蒙OS架構中,方舟編譯器和多終端開發IDE扮演着重要的位置。
跨平臺有一個最大的挑戰,那就是各個平臺的適配問題,尤爲是目前各類設備類型愈來愈多,如何將同一個應用,在手機、手錶、汽車、電視上面均可以適配的展現呢?這就是多終端開發IDE所作的事情。
使用華爲提供的多終端IDE,多語言統一編譯,分佈式架構Kit提供屏幕布局控件以及交互的自動適配,支持控件拖拽,面向預覽的可視化編程,從而使開發者能夠基於同一工程高效構建多端自動運行App,實現真正的一次開發,多端部署,在跨設備之間實現共享生態。
上圖就是華爲提供的IDE,在裏面能夠經過圖形化界面拖拽控件,而且IDE能夠幫助自動適配各類終端設備。
有了IDE,開發能夠方便的開發一套代碼,這樣能夠自動適配到各類設備中,可是各類設備所執行的機器指令是不同的,如何把這一套代碼分別編譯成各個設備須要的機器指令呢?
Android設備是由不一樣設備上內置的虛擬機進行編譯的,因此編譯以前就知道這個設備具體是什麼了,那麼,鴻蒙OS是怎麼作的呢?這就是方舟編譯器所幹的事情了。
華爲方舟編譯器是首個取代Android虛擬機模式的靜態編譯器,可供開發者在開發環境中一次性將高級語言編譯爲機器碼。此外,方舟編譯器將來將支持多語言統一編譯,可大幅提升開發效率。
Android之因此"慢",是由於他的編譯過程是在終端進行的,也就是說須要在用戶的手機上,經過虛擬機進行編譯成可執行的機器代碼。
而鴻蒙OS使用的方舟編譯器,能夠將高級語言(Java)直接變成機器碼,從而繞過了虛擬機。而且這個編譯過程並非在用戶的手機上完成的,而是在應用開發階段就完成了。
經過方舟編譯器,開發者的應用在下載以前就已經轉化成爲機器能夠識別的代碼,於是能夠在手機上快速安裝、啓動和運行,而無需在通過 VM 的編譯——某種程度上,方舟編譯器是將編譯過程提早到應用開發階段,從而大幅度減小了智能手機和操做系統的運行負擔。
華爲官方介紹,方舟編譯器是首家徹底替代語言虛擬機的靜態編譯器,徹底不須要解釋器。兼顧Java開發效率和C語言運行效率的編譯器。
除了代碼編譯,方舟編譯器也提供了更高效的內存機制,它與 Android 內存回收的不一樣之處在於:
Android 在內存回收上採用集中回收機制,發聲全局回收時更須要暫停應用,這也是隨機卡頓的根因之一。而方舟編譯器採用了引用計數法來進行內存的實時回收,而且配合使用了專門的消除環算法(消除對象互相引用帶來的沒法回收問題),來避免 GC 集中式回收帶來的系統卡頓。相比 GC,方舟的內存回收是實時的而非集中式的,且不須要暫停應用進程,這樣便大大消除了卡頓。
另外,就像JVM其實也是支持多種語言同樣,華爲表示,方舟編譯器將來也會支持更過的開發語言。換句話說,其餘語言的開發者,往後也能開發基於鴻蒙OS的應用。
https://www.zhihu.com/question/339567108 https://www.cnbeta.com/articles/tech/876171.htm https://www.cnbeta.com/articles/tech/876919.htm https://juejin.cn/post/6844903817637691400