1. 程式人生 > >mono ios莫名其妙閃退的解決方法

mono ios莫名其妙閃退的解決方法

使用mono進行ios開發也有一年了,一直有個頭疼的問題是閃退,而且閃退的時候並沒有丟擲明確的錯誤。

前兩天在除錯一個bug的時候,在序列化的時候又莫名其妙的閃退,後來在一位大神(部落格地址)的指導下,發現瞭解決方案!

遇到這種閃退,一般在Application output中輸出錯誤如下:

    ……………………
    0x01e394ac monoeg_g_log + 208 6 TrackAboutIOS
    0x01d11664 get_numerous_trampoline + 160 7 TrackAboutIOS
    ……………………
    =================================================================
          Got a SIGSEGV 
while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application. =================================================================

而且這種錯誤是隨機的,有時候正常執行,有時候不正常,在上文輸出錯誤內容裡我們看到trampoline這個單詞,而第一句monoeg_g_log 這句話是說系統在嘗試記錄錯誤到錯誤日誌,基於這種情況下,我們可以判定這是mono的預設蹦床(trampoline)數小於了你應用需要的蹦床數。

關於蹦床數的解釋,這裡Rolf Bjarne Kvinge給了相應的解釋:相應連結

On device we generate all the necessary code at build time in a process known as Ahead of Time compilation (similar to Microsoft's ngen), because we're not allowed to jit code on devices. Unfortunately there are a few things that cannot be determined statically - for instance generic interfaces might need different vtables depending on which type the interface is instantiated with. (For this case it is technically possible to determine the maximum number of vtables, but the number would be potentially enormous - multiply the number of generic interfaces times the number of types in your app...). We cannot allocate memory for these vtables dynamically at runtime, so we've picked a reasonable default and allow the user to increase this value if they run into issues. This is the basic theory for the trampolines (the exact problem is a bit different, depending on the type of trampolines, but that's not really important).

So you can add as many trampolines as you want, but memory usage will increase. That's also all there is to it: the app will not get slower (unless if the increased memory usage causes it to run slower, due to out-of-memory warnings, etc). It also means that you only have to increase the number of trampolines of the type you're actually having problems with, if you increase the others you'll increase the size of your executable needlessly.

大體意思是(英語不大好,盡力翻譯了):

因為mono不允許在蘋果裝置上即時編譯程式碼,所以在編譯的時候mono會通過AOT編譯技術直接編譯為ARM彙編程式碼。但在編譯的時候仍有一些無法靜態確定的事情:例如泛型介面可能需要不同的虛擬表(執行時存放執行方法的集合),這取決於介面被例項化時的型別。(對於這種情況,從技術上講確定虛擬表的最大數量是可能的,但是這數量可能會是龐大的--即泛型介面數乘以應用中型別數)……我們無法為這些虛擬表在執行時動態的分配記憶體,所以我們指定了一個合理的預設值並且允許使用者在執行時出現問題的情況下增加預設值。這就是蹦床的基本理論(實際情況略微不同,這依賴於蹦床數的型別,但這並不重要)

所以你可以按你的需要儘可能的增加蹦床數,但是記憶體的使用會增加。 應用一般不會變慢(除非記憶體的使用增多導致了記憶體不足,從而引起執行變慢)。這也同時意味著你只僅僅需要增加發生問題那塊對應的蹦床型別的數目。如果你增加了其他蹦床型別的數目,你也會不必要的增多了執行的體積。

看完這個,我想你對蹦床數有了一定了解,那如何設定呢!

開啟xamarin studio ,在專案檔案上右鍵option,展開下圖,在arguments引數的地方,輸入:-aot "nrgctx-trampolines=4096" -aot "nimt-trampolines=4096" -aot "ntrampolines=4096"

請看下圖:

QQ圖片20130906181222

我們在上面看到了-aot "nrgctx-trampolines=4096" -aot "nimt-trampolines=4096" -aot "ntrampolines=4096"這幾個輸入引數,那這幾個引數相對應的意思是什麼呢?

這裡官網給了我們解釋:連結地址

Ran out of trampolines of type 0
If you get this message while running device,  You can create more type 0 trampolines (type SPECIFIC) by modifying your project options "iPhone Build" section.  You want to add extra arguments for the Device build targets:

-aot "ntrampolines=2048"

The default number of trampolines is 1024.  Try increasing this number until you have enough for your application.

Ran out of trampolines of type 1
If you make heavy use of recursive generics, you may get this message on device.  You can create more type 1 trampolines (type RGCTX) by modifying your project options "iPhone Build" section.  You want to add extra arguments for the Device build targets:

-aot "nrgctx-trampolines=2048"

The default number of trampolines is 1024.  Try increasing this number until you have enough for your usage of generics.

Ran out of trampolines of type 2
If you make heavy use interfaces, you may get this message on device.  You can create more type 2 trampolines (type IMT Thunks) by modifying your project options "iPhone Build" section.  You want to add extra arguments for the Device build targets:

-aot "nimt-trampolines=512"

The default number of IMT Thunk trampolines is 128.  Try increasing this number until you have enough for your usage of interfaces.

下面進行翻譯一下:

Ran out of trampolines of type 0
如果你再執行時,輸出這個錯誤,你可以在專案option--iphone build處新增額外的引數-aot "ntrampolines=2048"
這個引數預設值為1024,試著增加這個值直到滿足你的應用的需求。
Ran out of trampolines of type 1
如果你使用了過多的泛型巢狀,如List<T>中還有List<T>成員,你可以同上通過新增額外的引數-aot "nrgctx-trampolines=2048" 來解決。
蹦床型別1的預設值為1024.
Ran out of trampolines of type 2
如果你介面操作頻繁,你可以通過新增額外的引數-aot "nimt-trampolines=512" 來解決。
這裡的預設值為128.