为什么我们的 MonoTouch 应用程序会破坏垃圾收集器?并不是内存不足

2024-04-13

我们的问题很简单,但原因却很复杂。我们是经验丰富的开发人员,并且对可能导致此问题的原因进行了大量研究。我们希望 MonoTouch 开发人员能够与我们合作,找出人们所遇到的常见问题,以及目前尚无解决方案的问题。我们已经为此工作了两个多星期,但未能解决。

问题是:为什么我们的 MonoTouch 应用程序会破坏垃圾收集器?它并没有失忆。

情况是我们有一个应用程序定期检查 Web 服务(可能每 5 秒一次)。一段时间后,它会因内存管理中止而失败。这通常发生在大约一个半小时后,但也可能持续十分钟到过夜。这种情况发生在我们所有的测试设备上(我们总共有 7 个设备,涵盖 iOS3 和 iOS4、iPod Touch、iPhone 和 iPad(1 和 2)。查看 StackOverflow 后,我们在计时器中添加了一个 System.Gc.Collect,然后再进行任何操作。这稍微改善了一些情况(失败需要更长的时间),但它并没有消失。还值得补充的是,iPad 的内存日志显示有 777 个空闲块,我们的应用程序正在使用 2041 个块,总共有 26488 个有线页面。由于我们已经进行了垃圾收集,并且没有做任何与 5 秒前所做的不同的事情,所以内存不足似乎很奇怪。

我们升级到了 MonoTouch 4.0.1,但这并没有修复它。

StackOverflow 问题可能涉及同一问题,但没有回答:5666905 https://stackoverflow.com/questions/5666905 / 4545383 https://stackoverflow.com/questions/4545383 / 5492469 https://stackoverflow.com/questions/5492469 / 5426733 https://stackoverflow.com/questions/5426733

iPad2 上发生故障的堆栈如下。失败可能发生在主线程或 http 线程中,但总是发生在这个 GC_ 序列中。我在下面包含了内存管理器 GC_remap 的代码,并进行了讨论。


Thread 10 Crashed:
0   libsystem_kernel.dylib  0x34b4da1c __pthread_kill + 8
1   libsystem_c.dylib       0x3646a3b4 pthread_kill + 52
2   libsystem_c.dylib       0x36462bf8 abort + 72
3   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 + 36
6   libsystem_c.dylib       0x3646a3b4 pthread_kill + 52
7   libsystem_c.dylib       0x36462bf8 abort + 72
8   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 + 52
20  MyApp                   0x002cff5c string_ToLower_System_Globalization_CultureInfo + 56
21  MyApp                   0x003e6ac0 System_Net_WebRequest_GetCreator_string + 40
22  MyApp                   0x003e694c System_Net_WebRequest_Create_System_Uri + 48
23  MyApp                   0x003e68d8 System_Net_WebRequest_Create_string + 64
24  MyApp                   0x004489c4 MyApp_Services_Client_GetResponseContent_string + 152
25  MyApp                   0x00446288 MyApp_Services_Client_GetCurrentQuestion_long_long + 916
26  MyApp                   0x00196fcc MyApp_Iphone_RootViewController_RetrieveCurrentQuestion + 868
27  MyApp                   0x002e6368 System_Threading_Thread_StartUnsafe + 168
28  MyApp                   0x00306890 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 192
29  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 + 242
37  libsystem_c.dylib       0x3646bbb4 thread_start + 0
  

这是 GC_remap 代码,似乎是失败点,来自https://github.com/mono/mono/blob/master/libgc/os_dep.c 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 上的处理方式有所不同?

代码位于https://github.com/mono/mono/blob/master/libgc/allchblk.c https://github.com/mono/mono/blob/master/libgc/allchblk.cGC_allochblk_nth 意味着仅当找到的内存块有效时才会调用 GC_remap 函数。 (该文件与堆栈跟踪的行号不太匹配,因此推测它不是完全相同的文件。)

http://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man2/mprotect.2.html http://developer.apple.com/library/ios/#documentation/System/Conceptual/ManPages_iPhoneOS/man2/mprotect.2.html说它可能会失败, EACCES、EINVAL、ENOTSUP 分别为 13、22 和 45。 SO 的一份报告称他们收到错误 12 (ENOMEM)。我不确定这意味着什么,因为 mprotect 不应该分配内存,并且文档没有说这是有效的。

更通用的文档位于http://linux.die.net/man/2/mprotect http://linux.die.net/man/2/mprotect表示 ENOMEM 可能是由于“无法分配内部内核结构。或者:[addr, addr+len]范围内的地址对于进程的地址空间无效,或者指定了一个或多个未映射的页面。 ”怎么会这样?

我们非常感谢任何有关我们如何推进这一工作的建议。除了 C# 代码之外,我们没有做任何事情,除了定期 https 读取之外,我们没有做任何事情。我们可以做些什么来改进调试(我们无法跟踪任何内容,因为应用程序被 iOS 杀死了)。我们尝试创建一个更简单的演示,但它的失败速度不够快,不值得使用。如果 Novell MonoTouch 开发人员想要我们的源代码,我们可以在明显保密的情况下提供。


感谢您的复制,我们发现并纠正了垃圾收集器中一个非常模糊的问题。它将包含在 MonoTouch 4.0.2 中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我们的 MonoTouch 应用程序会破坏垃圾收集器?并不是内存不足 的相关文章

随机推荐

  • 如何验证字符串是否是有效的浮点数? [复制]

    这个问题在这里已经有答案了 我想做的是验证字符串是否是数字 浮点数 但我还没有找到可以执行此操作的字符串属性 也许没有一个 我对这段代码有问题 N raw input Ingresa Nanometros if N and N isdigi
  • 在 Wheezy 7.8 (Raspbian) 上安装 R 3.1.2 失败

    我是 Linux 新手 尝试在我的 Raspberry 上安装最新的 R 版本 我的 Raspberry 在 Wheezy 7 8 上运行 我按照指示操 作on CRAN http cran r project org bin linux
  • Java 中 Component 的 componentResized 事件,但仅在鼠标释放时执行

    当我的一个组件 画布 调整大小时 我需要进行一些计算 不幸的是 计算可能需要几百毫秒 这会导致调整大小在完成时严重滞后 我想通过仅在调整大小结束时 我猜是释放鼠标按钮时 进行计算来解决这个问题 我怎样才能做到这一点 到目前为止我只有以下内容
  • BigQuery 无法将字段的“null”解析为 int

    尝试将 csv 文件加载到 bigquery 表中 有些列的类型为 INTEGER 但某些缺失值为 NULL 所以当我使用命令 bq load 加载时 出现以下错误 无法将 null 解析为字段的 int 所以我想知道处理这个问题的最佳解决
  • 默认 UITableView 分隔符的 UIColor 是什么?

    谁能告诉我默认 iPhone UITableView 分隔符的 UIColor 名称或确切的 RGBA 看起来像浅灰色 但其实不是 UIColor lightGrayColor 它比那轻 不保证颜色是特定颜色 它可以根据操作系统和 SDK
  • 4.5中的CallerMemberName属性“可以伪造”吗?

    因此 NET 4 5 引入了CallerMemberNameAttribute 这对于任何使用 WPF 并实施 WPF 的人来说似乎都是天赐之物INotifyPropertyChanged 我的问题是这样的 该属性本质上是由 4 5 5 0
  • Python GTK3:如何创建Gtk.FileChooseDialog?

    如何正确创建 Gtk FileChooseDialog 这个流行的教程 http python gtk 3 tutorial readthedocs io en latest dialogs html id2说使用如下代码 import g
  • 没有这样的表:(代码1)编译时:SELECT * FROM event

    首先 请不要将此问题标记为重复 因为我已经搜索了 stackoverflow 上关于此错误的每个问题 但仍然没有任何帮助 我尝试增加数据库版本 卸载并重新安装应用程序 尝试不同的模拟器 甚至在实际手机上尝试过 这是我的日志猫 04 26 1
  • Java NIO ZipFileSystem:创建文件系统时“未找到 zip END header”

    我在这里问这个问题是因为谷歌搜索这个错误只会让我在编写 zip 文件时得到点击 而我只是想阅读它 我有一个单元测试 我试图测试以下生产代码 Map
  • 如何让智能感知适用于 XLAM 文件中的 UDF?

    我的 XLAM 文件中有一些 UDF 当 XLAM 作为加载项安装时 Intellisense 似乎不会拾取这些 UDF UDF 本身在 Excel 中运行良好 只是它们不会出现在智能感知中 这里我指的是在工作表上使用时的智能感知 没有办法
  • 列表视图过滤器 Android

    我在android中创建了一个列表视图 我想在列表上方添加编辑文本 当用户输入文本时 列表将根据用户输入进行过滤 谁能告诉我是否有办法在android中过滤列表适配器 在列表视图的 xml 布局文件中添加一个 EditText 在你的活动
  • 错误处理响应:TypeError:self.processResponse 不是函数

    在 Devtool 控制台 中出现此错误 错误处理响应 TypeError self processResponse 不是函数 已解决的问题 似乎是由于 运行的 chrome 扩展导致此问题发生
  • iframe Google 地图无法在 Chrome 中打印

    自从最新的 Google 地图更新以来 我无法通过 Chrome 浏览器打印地图 如果我尝试用 Firefox 打印它并查看预览 地图就会显示出来 My code It displays the fol
  • Cassandra 用于无模式数据库、数十百万个订单表和每天数百万个查询

    我正在建立一个数据库 具有以下特点 每行的列数可变的无模式数据库 数千万条记录和数十列 每天有数百万次查询 每天有数千篇文章 查询将在多个列上进行过滤 不仅仅是键 我正在考虑按比例构建的 Cassandra 我的问题是 在这种情况下我需要水
  • 让 Google 搜索回归 Python

    我正在尝试从 Google 搜索中获取前 20 个结果 当我使用urllib2 urlopen 它给了我一个错误并说我被禁止了 我听说这与伪造用户代理字符串有关 但我几乎没有 urllib2 经验 如果有人可以提供帮助 我将非常感激 谢谢
  • 将列表传播到父代 sexp 中

    在任何 lisp 中是否有一种形式可以在父 sexp 中 传播 列表 喜欢 spread 1 2 3 gt 1 2 3 有两种方法可以做到这一点 哪个更好取决于您最终想要什么 一般来说 您可以使用 inside 反引号 表格如下 被评估以生
  • 如何在 SelectList 文本描述中组合两个字段?

    我想在选定的列表中放入 EF 模型人员的姓名标签 我尝试过这个 public ActionResult Insert ViewData accountlist new SelectList time Anagrafica Dipendent
  • Swift:如何扩展路径字符串中的波形符

    如何在 Swift 中用波形符扩展路径字符串 我有一个像这样的字符串 Desktop 我想使用这条路径NSFileManager方法 这需要将波形符扩展为 Users
  • Heroku:登录系统 - 身份验证循环失败

    我正在尝试登录我的 heroku 帐户 我不断收到一条错误消息 显示 您的登录出现问题 没有详细说明问题所在 我尝试通过 忘记密码 操作更改密码 但仍然被引导回到上述错误消息 我无法联系 Heroku 的支持团队 因为我无法登录 有没有人发
  • 为什么我们的 MonoTouch 应用程序会破坏垃圾收集器?并不是内存不足

    我们的问题很简单 但原因却很复杂 我们是经验丰富的开发人员 并且对可能导致此问题的原因进行了大量研究 我们希望 MonoTouch 开发人员能够与我们合作 找出人们所遇到的常见问题 以及目前尚无解决方案的问题 我们已经为此工作了两个多星期