关于热更的杂记
JIT與AOT
ILRUNTIME可以根據平臺設置,如果是安卓就用JIT,如果是IOS就用解釋器來解釋執行
關于IOS為什么不能通過DLL熱更
原因:UNITY在IOS上是AOT編譯的,即在程序運行前已經將IL代碼編譯成了本地機器碼,
https://blog.csdn.net/yy405145590/article/details/41282669?locationNum=14
【編譯MONO源碼實現代碼熱更】
MONO源碼中有一個接口mono_image_open_from_data_with_name,功能是用來加載Assembly-CSharp.dll,
這個接口在安卓與IOS都一樣,在安卓上可以通過修改它來實現熱更,在IOS卻不行,猜測原因:
1,安卓支持JIT,mono_image_open_from_data_with_name返回的IL代碼可以在程序運行時邊解釋邊執行
2,IOS,U3D在IOS平臺執行的是FULL AOT,即在IPA安裝時調用mono_image_open_from_data_with_name來加載Assembly-CSharp.dll并進行編譯,生成本地機器碼并存儲到手機上,以后每次運行執行的都是安裝時生成的機器碼,所以實現不了熱更
參考資料:https://blog.csdn.net/yy405145590/article/details/41282669?locationNum=14
這個接口
參考:
1,https://www.iteye.com/blog/wanzhanzhuce-2265055
2,我們知道C#腳本首先會被編譯成IL代碼,然后再由CLR從內存中讀取這些IL代碼并將其轉化為原生代碼,這是.NET程序的運行機制,而Mono是.NET在開源社區中的一種實現,Mono對C#代碼的編譯分為兩種,即即時編譯JIT(動態)和提前編譯AOT(靜態),這是Mono能為我們提供的兩種編譯方式。而從客觀上來講,iOS禁止通過JIT這種方式來編譯,所以你無法繞過AppStore直接對程序進行更新,因為即使你更新了C#腳本,由于這些腳本是沒有經過編譯的,它是無法直接運用到實際環境里的,而使用Lua進行熱更新,實際上改變的是應用層的邏輯,核心邏輯依然是在游戲發布時就和應用程序一起打包了,因為Lua無需編譯,所以它可以像普通文本資源一樣更新,和C#一樣Lua無法在運行時期間產生新的代碼,它永遠都是調用已存在的代碼。所以綜上所述,Unity引擎在iOS上無法熱更新的關鍵是在iOS系統禁止了即時編譯JIT這種權限,這個鍋Unity和Mono都不背,謝謝!
Mono在Full AOT模式下的限制
https://www.cnblogs.com/tekkaman/p/3973452.html?utm_source=tuicool&utm_medium=referral
AOT是在安裝時執行編譯的,比如基于UNITY的APK安裝時,會將IL代碼編譯為本機的本地代碼,保存在手機的存儲中,
因此AOT會使增加安裝時間。
好處是: 程序啟動快,內存占用小,包體小
JIT是運行開一個線程,一邊編譯一邊執行,一般以函數為單位,編譯過的機器碼會緩存起來,下一次用到時直接取用。
IOS禁用JIT的原理是:禁用了堆上的代碼執行權限。
參考資料:
1,https://www.zhihu.com/question/23874627
2,https://www.jianshu.com/p/a07bd632337a
3,https://www.cnblogs.com/murongxiaopifu/p/4278947.html
利用domain進行熱更的原理:
https://www.cnblogs.com/Leo_wl/p/4255533.html
?
unity熱更- 2 游戲大版本更新和熱更新
https://blog.csdn.net/u014748818/article/details/78812728?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
?
Unity Android 動態更新 Assembly-CSharp.dll
http://blog.sina.com.cn/s/blog_9e5d42ee0102vvtg.html
總結
- 上一篇: 关于unityengine.dll, u
- 下一篇: ‘xxfile' Missing the