实例化NSObject会导致内存不足崩溃

时间:2011-03-24 23:15:41

标签: xamarin.ios

运行以下代码时,应用程序崩溃(大约30秒后)使用下面的堆栈跟踪。我发现这很奇怪,因为我希望垃圾收集器清理这个内存。我们的应用程序具有类似的模式和崩溃与类似的堆栈跟踪。

注释掉实例化NSObject成员的行会使应用程序运行而不会崩溃。注释掉实例化字节数组的行会使应用程序运行得更长,但它仍会崩溃。

仪器报告应用程序和仪器的相当稳定的实时字节数导致应用程序运行更长时间而不会崩溃,但它仍然会崩溃(大约10分钟后)。不断的Live Bytes让我觉得垃圾收集器正在工作。

代码:

using System.Threading;
using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace MyExample
{
    public class Application
    {
        static void Main (string[] args)
        {
            UIApplication.Main(args);
        }
    }

    public partial class AppDelegate : UIApplicationDelegate
    {
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            Thread testThread = new Thread(BreakMe);
            testThread.Start();

            window.MakeKeyAndVisible();
            return true;
        }

        private void BreakMe()
        {
            while(true)
            {
                using (var arPool = new NSAutoreleasePool())
                {
                    MyGarbage garbage = new MyGarbage();
                }
            }
        }

        private class MyGarbage
        {
            byte[] _Foo = new byte[100000];
            NSObject _Bar = new NSObject();
        }
    }
}

申请表输出:

Mprotect failed at 0x493c000 (length 4096) with errno 12
Stacktrace:

  at (wrapper managed-to-native) System.Array.CreateInstanceImpl (System.Type,int[],int[]) <0xffffffff>
  at System.Array.CreateInstance (System.Type,int[]) <0x000bc>
  at System.Array.CreateInstance (System.Type,int) <0x00057>
  at System.MonoCustomAttrs.GetCustomAttributes (System.Reflection.ICustomAttributeProvider,System.Type,bool) <0x000db>
  at System.MonoCustomAttrs.GetCustomAttribute (System.Reflection.ICustomAttributeProvider,System.Type,bool) <0x00033>
  at System.Attribute.GetCustomAttribute (System.Reflection.MemberInfo,System.Type,bool) <0x0003f>
  at MonoTouch.ObjCRuntime.Class.GetHandle (System.Type) <0x00037>
  at MonoTouch.Foundation.NSObject.AllocIfNeeded () <0x00063>
  at MonoTouch.Foundation.NSObject..ctor (MonoTouch.Foundation.NSObjectFlag) <0x00027>
  at MonoTouch.Foundation.NSAutoreleasePool..ctor () <0x00037>
  at MyExample.AppDelegate.BreakMe () [0x00000] in Main.cs:30
  at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0x000cb>

Native stacktrace:

    0   MyExample                       0x002db308 mono_handle_native_sigsegv + 404
    1   MyExample                       0x002fa5dc sigabrt_signal_handler + 148
    2   libsystem_c.dylib                   0x369c972f _sigtramp + 42
    3   libsystem_c.dylib                   0x369be3bb pthread_kill + 58
    4   libsystem_c.dylib                   0x369b6bff abort + 78
    5   MyExample                       0x0041e484 GC_remap + 200
    6   MyExample                       0x00411ee4 GC_allochblk_nth + 1536
    7   MyExample                       0x00411894 GC_allochblk + 96
    8   MyExample                       0x0041d94c GC_new_hblk + 116
    9   MyExample                       0x00413c3c GC_allocobj + 188
    10  MyExample                       0x0041859c GC_generic_malloc_inner + 352
    11  MyExample                       0x004187ac GC_generic_malloc + 132
    12  MyExample                       0x00418c60 GC_malloc + 208
    13  MyExample                       0x003a67dc mono_object_allocate + 64
    14  MyExample                       0x003a7240 mono_array_new_full + 828
    15  MyExample                       0x00341324 ves_icall_System_Array_CreateInstanceImpl + 896
    16  MyExample                       0x0012cf3c (wrapper managed-to-native) System.Array:CreateInstanceImpl (System.Type,int[],int[]) + 80
    17  MyExample                       0x0012d23c System.Array:CreateInstance (System.Type,int) + 88
    18  MyExample                       0x0018b70c System.MonoCustomAttrs:GetCustomAttributes (System.Reflection.ICustomAttributeProvider,System.Type,bool) + 220
    19  MyExample                       0x0018b560 System.MonoCustomAttrs:GetCustomAttribute (System.Reflection.ICustomAttributeProvider,System.Type,bool) + 52
    20  MyExample                       0x00131fd0 System.Attribute:GetCustomAttribute (System.Reflection.MemberInfo,System.Type,bool) + 64
    21  MyExample                       0x000795ec MonoTouch.ObjCRuntime.Class:GetHandle (System.Type) + 56
    22  MyExample                       0x00077e60 MonoTouch.Foundation.NSObject:AllocIfNeeded () + 100
    23  MyExample                       0x0007779c MonoTouch.Foundation.NSObject:.ctor (MonoTouch.Foundation.NSObjectFlag) + 40
    24  MyExample                       0x00074d10 MonoTouch.Foundation.NSAutoreleasePool:.ctor () + 56
    25  MyExample                       0x00002c34 MyExample.AppDelegate:BreakMe () + 164
    26  MyExample                       0x001f3e3c (wrapper runtime-invoke) object:runtime_invoke_dynamic (intptr,intptr,intptr,intptr) + 204
    27  MyExample                       0x002c4658 mono_jit_runtime_invoke + 3032
    28  MyExample                       0x003a34a8 mono_runtime_invoke + 140
    29  MyExample                       0x003a48f0 mono_runtime_delegate_invoke + 136
    30  MyExample                       0x003cb31c start_wrapper + 752
    31  MyExample                       0x003f09a0 thread_start_routine + 240
    32  MyExample                       0x0041f9ac GC_start_routine + 132
    33  libsystem_c.dylib                   0x369be311 _pthread_start + 248
    34  libsystem_c.dylib                   0x369bfbbc start_wqthread + 0

2 个答案:

答案 0 :(得分:2)

对此的真正答案是,怀疑是Why is our MonoTouch app breaking in the garbage collector? It is not out of memory中的问题已解决,这是一个内存管理器问题。堆栈跟踪对我来说非常熟悉。

答案 1 :(得分:1)

您已将分配器与垃圾收集器进行竞争。如果您对演示进行了简单的更改并添加:

System.GC.Collect ();

在循环中,您将看到它不再崩溃。

这里发生的事情是你尽快分配。当GC耗尽内存时,它会扩展堆并收集。接下来几次循环运行它会运行一段时间,然后由于expaned堆再次收集,但最终会失败。

在我放弃之前,进行上述的小修改允许测试在这里运行10分钟。