如何解決IOS可執行文件TEXT段超標
最近要做IOS測試,提交的時候不幸發現提交失敗,可執行文件的TEXT段超過了80M。因為當時是出測試包,就強行修改成APP只支持9.0以上來解決。但是正式版可不能這麼干,必須做一些優化。
Unity的IL2CPP技術會將C#代碼的編譯結果翻譯成C++代碼,這個翻譯過程中會產生大量的代碼。儘管Unity的新版本已經比早起版本優化很多了,但是很不幸,我們還是超標了。
解決問題的思路還是提出問題,分析問題,解決問題。其實我對這塊也不是很熟悉,查閱了一些資料之後就開始優化,以下記錄了優化過程。
查看可執行文件段大小首先進行Archives。Mac系統使用XCode生成項目之後,生成的執行文件都在DerivedData目錄下。可以使用Command
+ Shift + G跳轉,目標地址:~/資源庫/Developer/Xcode/DerivedData/
進入生成的目錄,找到包CN,查看包內容,找到同名的可執行文件。打開終端,進入對應目錄,使用命令size即可顯示可執行文件的各段的大小:
MacBook-Pro:WorkS hanyufei$ size ./cn
__TEXT __DATA __OBJC others dec hex
40370176 3932160 0 1884160 46186496 2c0c000 ./cn (for
architecture armv7)47300608 5947392 0 4296228864 4349476864 1033fc000
./cn (for architecture arm64)第一列是TEXT段的大小,上下分別對應Armv7和Arm64,可見兩者之和超過了80M。
如果想要看到更具體一些的信息,還可以使用MachOView。下載之後運行,使用Open打開可執行文件,然後可以看到更詳細的信息:
可以看到主要的空間還是代碼,常量,字元串,方法名等佔用的並不多。
分析LinkMap如果更進一步想要看到更具體的每個文件的信息可以使用LinkMap。首先需要開啟LinkMap,記錄LinkMap文件的位置。
- 在Archives的同級目錄下,找到LinkMap文件
/Users/hanyufei/Library/Developer/Xcode/DerivedData/Unity-iPhone-ffsoehaumctgaoadknrgjgvfcbsc/Build/Intermediates.noindex/Unity-iPhone.build/ReleaseForRunning-iphoneos/Unity-iPhone.build
- 使用WMLinkMapAnalyzer的工具進行分析(原文鏈接:http://blog.csdn.net/wm9028/article/details/50462320)
可以看到一些第三方的庫比較大,但是代碼部分還是得不到比較明確的結果。那乾脆直接一點,去看生成工程的Native文件的大小。
分析Native目錄在導出的XCode工程目錄下的Classes目錄下可以找到到Native目錄,可以看到它的大小是非常大的,佔用了369.4M。推算一下只要超過了300M就有可能導致超標。
進行一些更詳細的分析:
可見一些庫占和一些導表相關的功能佔用的比較大,相關同事做了優化和精簡。
另外一個同事找了https://github.com/terryyin/lizard的分析工具做了一下排序,可以更清晰的看到類的大小:
優化方案:- 找到了瓶頸之後,我們開始進行優化,在優化的過程中又接了SDK導致可執行文件更大,又進行多次優化。
- Unity的一些優化設置,這部分基本已經是最優了。
- 刪除無用代碼,減少了Lua的導出文件(可以嘗試自動化的工具,但是會有些風險)。
- 刪除無用庫和插件,一些必須使用的庫使用更輕量的庫
- 反射和泛型
- 把TEXT段中不用的數據移到RODATA只讀數據段
-Wl,-rename_section,__TEXT,__cstring,__RODATA,__cstring
-Wl,-rename_section,__TEXT,__gcc_except_tab,__RODATA,__gcc_except_tab
-Wl,-rename_section,__TEXT,__const,__RODATA,__const
-Wl,-rename_section,__TEXT,__objc_methname,__RODATA,__objc_methname
-Wl,-rename_section,__TEXT,__objc_classname,__RODATA,__objc_classname
-Wl,-rename_section,__TEXT,__objc_methtype,__RODATA,__objc_methtype
- 其他
優化結果:
__TEXT __DATA __OBJC others dec hex
35323904 4276224 0 6946816 46546944 2c64000 ./cn (for
architecture armv7)39469056 6733824 0 4303519744 4349722624 103438000
./cn (for architecture arm64)可見優化成果喜人。經過以上簡單優化後,Native容量大幅減少,部分代碼段的內容也移到了只讀段,最終通過了檢測。因為後續集成了58M的SDK,所以TEXT的大小看上去只減少了一點,如果SDK再做一些優化的話包體可以更小。因為測試時間比較緊迫,此次優化還是非常保守的。
參考資料:
http://www.cnblogs.com/bodong/p/4804240.html
http://blog.csdn.net/wm9028/article/details/50462320
http://everettjf.com/2016/08/19/facebook-explore-section-rodata/
推薦閱讀:
※App Store 有哪些好的 1 元 App?
※想利用ipad學習,在ipad上如何播放swf文件??
※iPhone 應用 Duolingo 學習外語的效率高嗎?體驗如何?
※在代碼中加入"時間欺騙",蘋果審核的時候會發現嗎?
※為什麼就算我禁用了位置信息,釘釘的定位簽到還是可以順利運行?