本文介绍了为什么我们的MonoTouch应用程序会破坏垃圾收集器?它并没有内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我们有一个简单的问题,但原因很复杂。我们是经验丰富的开发人员,并对可能导致它的原因进行了大量研究。我们希望MonoTouch开发人员能够与我们合作,找出人们所面临的常见问题,而且目前还没有解决方案。我们已经为此工作了两个多星期,而且无法解决它。We have a simple question, but the cause is complicated. We are experienced developers, and have done a lot of research into what may be causing it. We are hoping that MonoTouch developers can work with us to identify what appears to be a common problem that people are having and for which no solution appears to exist yet. We've been working on this for over two weeks, and not been able to resolve it.问题是:为什么我们的MonoTouch应用程序会在垃圾收集器中崩溃?它不是内存不足。The question is: Why is our MonoTouch app breaking in the garbage collector? It is not out of memory.情况是我们有一个应用程序定期检查Web服务(可能每5秒)。经过一段时间后,内存管理中止失败。这通常在大约一个半小时后发生,但可以是从十分钟到过夜的任何地方。这种情况发生在我们所有的测试设备上(我们共有7个覆盖iOS3和iOS4,iPod Touch,iPhone和iPad(1& 2)。在查看StackOverflow之后,我们在计时器之前添加了一个System.Gc.Collect采取任何行动。这改善了一些事情(失败需要更长的时间),但它并没有消失。同样值得补充的是,来自iPad的记忆日志显示有777个免费区块,而我们使用的是2041个应用程序,共有26488个有线页面。由于我们收集了垃圾,并且没有做出与我们之前5秒做的不同的事情,内存耗尽似乎很奇怪。The situation is that we have an app that checks a web service regularly (perhaps every 5 seconds). After a period of time it fails with a memory management abort. This typically happens after about an hour and a half, but can be anywhere from ten minutes to overnight. This happens on all of our test devices (we have 7 in total covering iOS3 and iOS4, iPod Touch, iPhones and iPads (1&2). After looking on StackOverflow, we have added a System.Gc.Collect in a timer before we take any action. This improved things a little (it takes longer to fail), but it did not go away. It is also worth adding that the memory log from the iPad shows that there are 777 free blocks, and 2041 in use by our app, with a total of 26488 wired pages. Since we've garbage collected, and are not doing anything different to what we did 5 seconds before, it seems odd to run out of memory. 我们已升级到MonoTouch 4.0.1但尚未修复它。We upgraded to MonoTouch 4.0.1 but that has not fixed it. StackOverflow问题可能出现在同一问题上,但没有回答: 5666905 / 4545383 / 5492469 / 5426733 StackOverflow questions that might be on the same issue, but not answering it: 5666905 / 4545383 / 5492469 / 5426733 iPad2上出现故障的堆栈如下。失败可能发生在主线程或http线程中,但始终在此GC_序列中。我已经在下面列出了内存管理器GC_remap的代码,并进行了讨论。The stack at failure on an iPad2 is below. The failure can happen in the main thread or an http thread, but always goes in this GC_ sequence. I have included the code for the memory manager GC_remap below, with discussion.Thread 10 Crashed:0 libsystem_kernel.dylib 0x34b4da1c __pthread_kill + 81 libsystem_c.dylib 0x3646a3b4 pthread_kill + 522 libsystem_c.dylib 0x36462bf8 abort + 723 MyApp 0x004ca92c mono_handle_native_sigsegv (mini-exceptions.c:2249)4 MyApp 0x004f2208 sigabrt_signal_handler (mini-posix.c:195)5 libsystem_c.dylib 0x36475728 _sigtramp + 366 libsystem_c.dylib 0x3646a3b4 pthread_kill + 527 libsystem_c.dylib 0x36462bf8 abort + 728 MyApp 0x0061dc94 GC_remap (os_dep.c:2092)9 MyApp 0x00611678 GC_allochblk_nth (allchblk.c:730)10 MyApp 0x00611028 GC_allochblk (allchblk.c:561)11 MyApp 0x0061d0e0 GC_new_hblk (new_hblk.c:253)12 MyApp 0x006133d0 GC_allocobj (alloc.c:1116)13 MyApp 0x00617d30 GC_generic_malloc_inner (malloc.c:136)14 MyApp 0x00617f40 GC_generic_malloc (malloc.c:192)15 MyApp 0x00618264 GC_malloc_atomic (malloc.c:262)16 MyApp 0x005a46d4 mono_object_allocate_ptrfree (object.c:4221)17 MyApp 0x005a4aa0 mono_string_new_size (object.c:4848)18 MyApp 0x005c1b14 ves_icall_System_String_InternalAllocateStr (string-icalls.c:213)19 MyApp 0x002d34c4 wrapper_managed_to_native_string_InternalAllocateStr_int + 5220 MyApp 0x002cff5c string_ToLower_System_Globalization_CultureInfo + 5621 MyApp 0x003e6ac0 System_Net_WebRequest_GetCreator_string + 4022 MyApp 0x003e694c System_Net_WebRequest_Create_System_Uri + 4823 MyApp 0x003e68d8 System_Net_WebRequest_Create_string + 6424 MyApp 0x004489c4 MyApp_Services_Client_GetResponseContent_string + 15225 MyApp 0x00446288 MyApp_Services_Client_GetCurrentQuestion_long_long + 91626 MyApp 0x00196fcc MyApp_Iphone_RootViewController_RetrieveCurrentQuestion + 86827 MyApp 0x002e6368 System_Threading_Thread_StartUnsafe + 16828 MyApp 0x00306890 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 19229 MyApp 0x004b0274 mono_jit_runtime_invoke (mini.c:5746)30 MyApp 0x0059f924 mono_runtime_invoke (object.c:2756)31 MyApp 0x005a1350 mono_runtime_delegate_invoke (object.c:3421)32 MyApp 0x005ca884 start_wrapper_internal (threads.c:788)33 MyApp 0x005ca924 start_wrapper (threads.c:830)34 MyApp 0x005ef4b8 thread_start_routine (wthreads.c:285)35 MyApp 0x0061f1d0 GC_start_routine (pthread_support.c:1468)36 libsystem_c.dylib 0x3646a30a _pthread_start + 24237 libsystem_c.dylib 0x3646bbb4 thread_start + 0这是从 https://github.com/mono/mono/blob/master/libgc/os_dep.c #ifdef NACL { /* NaCl doesn't expose mprotect, but mmap should work fine */ void * mmap_result; mmap_result = mmap(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC, MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, zero_fd, 0/* offset */); if (mmap_result != (void *)start_addr) ABORT("mmap as mprotect failed"); /* Fake the return value as if mprotect succeeded. */ result = 0; }#else /* NACL */ result = mprotect(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC);#endif /* NACL */ if (result != 0) { GC_err_printf3( "Mprotect failed at 0x%lx (length %ld) with errno %ld\n", start_addr, len, errno); ABORT("Mprotect remapping failed"); } GC_unmapped_bytes -= len;看来ABORT是由mprotect函数失败引起的。我们无法获得失败代码,因为问题不会在模拟器上显现出来。 mprotect功能似乎只是将内存标记为可读/写/执行。内存管理器如何传递导致其失败的参数?可能是传递了错误的指针,还是错误的长度?或者iOS上的某些区域或边界处理方式不同?It would appear that the ABORT is caused by the mprotect function failing. We have been unable to get the failure code as the problem does not manifest itself on the simulator. The mprotect function appears to just mark the memory as accessible for read/write/execute. How is the memory manager passing parameters that cause it to fail? Could it be passing an incorrect pointer, or an incorrect length? Or are certain areas or boundaries handled differently on iOS? https://github.com/mono/mono/blob/master/libgc/allchblk.c 表示仅在调用GC_remap函数时调用GC_remap函数找到的内存块是有效的。 (此文件与堆栈跟踪的行号不完全匹配,因此可能不是完全相同的文件。)The code at https://github.com/mono/mono/blob/master/libgc/allchblk.c for GC_allochblk_nth implies that the GC_remap function is only called if the memory block found was valid. (This file doesn't quite match the line numbers of the stack trace, so presumably it is not exactly the same file.) http://developer.apple.com/library/ios/#文档/ System / Conceptual / ManPages_iPhoneOS / man2 / mprotect.2.html 表示它可能会失败,EACCES,EINVAL,ENOTSUP是13,22和&分别为45。有关SO的报告之一表示他们收到错误12(ENOMEM)。我不确定这意味着什么,因为mprotect不应该分配内存,文档也没有说这是有效的。http://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man2/mprotect.2.html says that it might fail with EACCES, EINVAL, ENOTSUP which are 13, 22, & 45 respectively. One of the reports on SO says that they get an error 12 (ENOMEM). I'm not sure what that means, as mprotect shouldn't be allocating memory, and the documentation doesn't say that is valid. http://linux.die.net/man/2/mprotect 表示ENOMEM可以导致无法分配内部内核结构。或者:[addr,addr + len]范围内的地址对进程的地址空间无效,或者指定一个或多个未映射的页面。这怎么可能?A more generic documentation at http://linux.die.net/man/2/mprotect indicates that ENOMEM can be caused by "Internal kernel structures could not be allocated. Or: addresses in the range [addr, addr+len] are invalid for the address space of the process, or specify one or more pages that are not mapped." How could this be?我们非常感谢有关如何推动这一进程的任何建议。除了C#代码之外,我们没有做任何事情,除了定期的https读取之外,我们没有做任何事情。我们可以做些什么来改善调试(我们无法追踪任何因为iOS杀死了应用程序)。我们已经尝试创建一个更简单的演示,但它不会快速失败,值得使用。如果Novell MonoTouch开发人员想要我们的源代码,我们可以提供明显的机密性。We would much appreciate any suggestions on how we might move this forward. We are not doing anything other than C# code, and are not doing anything other than a periodic https read. What can we do to improve debugging (we can't trace anything as the app is killed by iOS). We have tried creating a simpler demonstration, but it does not fail fast enough to be worth using. If a Novell MonoTouch developer wants our source, we can provide it subject to the obvious confidentiality.推荐答案感谢您的再现,我们有发现并纠正了垃圾收集器中一个非常模糊的问题。它将包含在MonoTouch 4.0.2中。Thanks to your reproduction we have found and corrected a very obscure issue in the garbage collector. It will be included in MonoTouch 4.0.2. 这篇关于为什么我们的MonoTouch应用程序会破坏垃圾收集器?它并没有内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-22 12:51