MonoTouch不稳定继续:受管内存分配器崩溃

| 长话短说:我可以分配大量的非托管内存,但是尝试在托管内存中分配相同数量(或更少)的内存会导致GC_remap(下面的调用堆栈)中的MonoTouch崩溃。 细节: 我将讨论上述行为的一个示例。我的应用偶尔会分配一个2.5MB的托管内存块(使用新的byte []),并且它经常在我的iPhone4上死机,并在下面粘贴了调用堆栈(即分配过程中的mprotect错误)。我没有对这些2.5MB的块进行引用的时间长于单个函数调用的时间。 MonoTouch的家伙说\ mprotect errno 12 \意味着您已经用尽了设备上的内存,但事实是,我的应用程序有很多可用的内存。我可以在应用程序启动时分配0MB,10MB或200MB的非托管内存(使用Marshal.AllocHGlobal),每隔一帧触摸一次,这会使我的应用程序行为或此mprotect错误的发生率零差异。 一些注意事项 GC.TotalMemory告诉我,我的应用始终处于3MB到5MB的托管内存使用量之间。 在我的应用程序中,我还有其他地方要分配更大的非托管内存块,并且它永远不会在那里崩溃。我创建了压力测试,加载了4MB(非托管)纹理数据,将其交给GL,然后每帧绘制一次,应用程序非常坚固,直到我开始要求大块托管内存为止。 除非我打电话给GC.Collect,否则GC.CollectionCount几乎不会更改。 MonoTouch 3.2.3和MonoTouch 4.0也会发生相同的行为。 我们所有的测试设备(iPhone 3G,3GS,4,iPad,iPad2)都发生相同的行为。 在发布版本和调试版本中会发生相同的行为,尽管在调试版本中会更频繁地发生。 引发崩溃的方法 如果我创建了一个调用GC.Collect的线程,然后休眠了1ms,这会使崩溃更快地发生(即,如果我在调试版本中,则几乎立即发生)。 使用某些.NET功能(如WebRequest)也会导致此崩溃。我只能假设它也在其中的某个位置分配了大块托管内存。 坠机的方法 有两种方法可以减少崩溃的频率或将其完全修复: 如果我预先分配了2.5MB的托管内存块,然后在应用程序的整个生命周期内都保留它,则不会崩溃。 如果在执行任何操作之前先固定2.5MB的内存块,那似乎会有所帮助。 结论/问题 由于此问题,我们尚未在我们的应用程序中实现完全稳定性。崩溃(总是在GC_remap内部)发生在整个应用程序中的随机分配中(我在这里拥有的2.5MB示例只是我选择隔离和复制的示例)。 问题: 我可以完全不信任托管分配器吗? 为什么我可以分配200MB的非托管内存,但是我要求2.5MB时托管分配器却死了? (注意:即使我没有分配200MB的非托管内存,当我要求2.5MB时,它也会消失)。 如果我在应用程序的整个生命周期中占用那2.5MB的空间,为什么该应用程序就可以正常使用,但是如果我将它还给系统(并调用GC.Collect)并在以后再请求另外的2.5MB,那么崩溃性会更糟!如果这确实是内存不足的情况,那么将2.5MB的内存还给系统比吞噬它更好吗? 我们甚至可以使用MonoTouch吗? 我的团队正在认真考虑放弃我们产品的MonoTouch,因为我们无法使其稳定可靠。 通过stackoverflow,在Novell网站上提交错误或直接通过电子邮件发送MonoTouch的支持电子邮件,我们也无法从MonoTouch团队那里获得时间。我们已经将(托管和非托管)内存使用量降低到了荒谬的低点,但是由于此问题,该应用程序仍然崩溃。 在短期内,我想到的唯一解决方法是在启动时分配一大块内存(2-5MB),将其PIN以便垃圾收集器永远不会触摸它,并编写我自己的分配器来分发部分根据需要将此内存块存储到我的应用中。但是,如果这是在MonoTouch下可能的最佳解决方案,那么我将尽快收回我的钱,只要我能从MonoTouch达到逃脱速度。 ...
Mprotect failed at 0xaa00000 (length 3801088) with errno 12
Stacktrace:

  at MyApp.GameScreen/VerifyPictureDialog.StoreBasePictureData () [0x00000] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:428
  at MyApp.GameScreen/VerifyPictureDialog.ApplyFilters (bool) [0x0004b] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:640
  at MyApp.GameScreen/VerifyPictureDialog.Simulate (single) [0x00077] in /Users/dussault/s/MyApp/Main/Src/PhotoScreens.cs:477
  at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
  at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
  at MyApp.GameScreen.Simulate (single) [0x00238] in /Users/dussault/s/MyApp/Main/Src/GameScreen.cs:3114
  at MyApp.BaseWindow.Simulate (single) [0x00007] in /Users/dussault/s/MyApp/Main/Src/BaseWindow.cs:56
  at MyApp.WindowMgr.Simulate (single) [0x0002f] in /Users/dussault/s/MyApp/Main/Src/WindowMgr.cs:126
  at MyApp.Game1.Update (Microsoft.Xna.Framework.GameTime) [0x0010f] in /Users/dussault/s/MyApp/Main/Src/Game1.cs:1194
  at Microsoft.Xna.Framework.Game.DispatchUpdate (Microsoft.Xna.Framework.GameTime) [0x00000] in /Users/dussault/s/MyApp/Main/Src/XNA-Emulation/GraphicsDevice.cs:531
  at MyApp_iOS.EAGLView.OnUpdateFrame () [0x00050] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:310
  at MyApp_iOS.EAGLView.SimulateAndRender () [0x0000a] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:279
  at MyApp_iOS.EAGLView.MainLoopTimerCallback () [0x00006] in /Users/dussault/s/MyApp/Main/Src/iOS/EAGLView.cs:231
  at MonoTouch.Foundation.NSActionDispatcher.Apply () <0x0002b>
  at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>
  at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x000cf>
  at MonoTouch.UIKit.UIApplication.Main (string[]) <0x00023>
  at MyApp_iOS.Application.Main (string[]) [0x00000] in /Users/dussault/s/MyApp/Main/Src/iOS/Main.cs:57
  at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

    0   MyApp_iOS                           0x00af1b48 mono_handle_native_sigsegv + 412
    1   MyApp_iOS                           0x00b1c66c sigabrt_signal_handler + 148
    2   libSystem.B.dylib                   0x33bd3ddf _sigtramp + 42
    3   libSystem.B.dylib                   0x33bd52cb kill + 10
    4   libSystem.B.dylib                   0x33bd52bd raise + 16
    5   libSystem.B.dylib                   0x33be9d79 abort + 56
    6   MyApp_iOS                           0x00c74378 GC_remap + 200
    7   MyApp_iOS                           0x00c62c04 GC_allochblk_nth + 1536
    8   MyApp_iOS                           0x00c625b4 GC_allochblk + 96
    9   MyApp_iOS                           0x00c6bf6c GC_alloc_large + 132
    10  MyApp_iOS                           0x00c6c5e8 GC_generic_malloc + 324
    11  MyApp_iOS                           0x00c6c8c8 GC_malloc_atomic + 332
    12  MyApp_iOS                           0x00bd8e88 mono_object_allocate_ptrfree + 64
    13  MyApp_iOS                           0x00bd8ff4 mono_array_new_specific + 148
    14  MyApp_iOS                           0x009173f4 wrapper_managed_to_native_object___icall_wrapper_mono_array_new_specific_intptr_int + 68
    15  MyApp_iOS                           0x002cd880 MyApp_GameScreen_VerifyPictureDialog_ApplyFilters_bool + 628
    16  MyApp_iOS                           0x002cbffc MyApp_GameScreen_VerifyPictureDialog_Simulate_single + 768
    17  MyApp_iOS                           0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
    18  MyApp_iOS                           0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
    19  MyApp_iOS                           0x002a71fc MyApp_GameScreen_Simulate_single + 2736
    20  MyApp_iOS                           0x002ef9d0 MyApp_BaseWindow_Simulate_single + 280
    21  MyApp_iOS                           0x0038068c MyApp_WindowMgr_Simulate_single + 376
    22  MyApp_iOS                           0x0027f798 MyApp_Game1_Update_Microsoft_Xna_Framework_GameTime + 1992
    23  MyApp_iOS                           0x0039afc8 Microsoft_Xna_Framework_Game_DispatchUpdate_Microsoft_Xna_Framework_GameTime + 148
    24  MyApp_iOS                           0x0026ec10 MyApp_iOS_EAGLView_OnUpdateFrame + 716
    25  MyApp_iOS                           0x0026e8cc MyApp_iOS_EAGLView_SimulateAndRender + 196
    26  MyApp_iOS                           0x0026e1cc MyApp_iOS_EAGLView_MainLoopTimerCallback + 296
    27  MyApp_iOS                           0x009a7dfc MonoTouch_Foundation_NSActionDispatcher_Apply + 44
    28  MyApp_iOS                           0x00912540 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
    29  MyApp_iOS                           0x00acc9c4 mono_jit_runtime_invoke + 2800
    30  MyApp_iOS                           0x00bd3ea4 mono_runtime_invoke + 140
    31  MyApp_iOS                           0x00c7d214 monotouch_trampoline + 2840
    32  Foundation                          0x3363b469 __NSFireTimer + 136
    33  CoreFoundation                      0x33a770a3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
    34  CoreFoundation                      0x33a76b5b __CFRunLoopDoTimer + 850
    35  CoreFoundation                      0x33a481b5 __CFRunLoopRun + 1088
    36  CoreFoundation                      0x33a47c87 CFRunLoopRunSpecific + 230
    37  CoreFoundation                      0x33a47b8f CFRunLoopRunInMode + 58
    38  GraphicsServices                    0x33b0e4ab GSEventRunModal + 114
    39  GraphicsServices                    0x33b0e557 GSEventRun + 62
    40  UIKit                               0x32099329 -[UIApplication _run] + 412
    41  UIKit                               0x32096e93 UIApplicationMain + 670
    42  MyApp_iOS                           0x009d484c wrapper_managed_to_native_MonoTouch_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 240
    43  MyApp_iOS                           0x009b4c00 MonoTouch_UIKit_UIApplication_Main_string__ + 36
    44  MyApp_iOS                           0x00269694 MyApp_iOS_Application_Main_string__ + 128
    45  MyApp_iOS                           0x00912540 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 200
    46  MyApp_iOS                           0x00acc9c4 mono_jit_runtime_invoke + 2800
    47  MyApp_iOS                           0x00bd3ea4 mono_runtime_invoke + 140
    48  MyApp_iOS                           0x00bd6f3c mono_runtime_exec_main + 784
    49  MyApp_iOS                           0x00bd5f6c mono_runtime_run_main + 1048
    50  MyApp_iOS                           0x00ad7940 mono_jit_exec + 216
    51  MyApp_iOS                           0x00ac2e38 main + 3536
    52  MyApp_iOS                           0x000133a0 start + 52

Debug info from gdb:


=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
    
已邀请:
Darwin内核过量使用内存。 这意味着如果您请求200兆的内存,即使它们不可用,您也将得到它们,并且只要您不实际消耗内存,应用程序就可以正常运行。 仅当您实际写入页面时,页面才会分配给您的进程。 适当的测试将要求您分配内存,然后填满已使用的内存,这就是为什么您可能会感到即使在没有内存的情况下也可以分配200兆内存的印象。 一个简单的程序将向您显示:尝试分配500兆,操作系统将显示“是的,您知道了”,但是没有iPhone具有这种内存。 一个简单的测试案例将大大有助于显示问题所在。     

要回复问题请先登录注册