xamarin.ios - 为什么此代码会导致 "Out Of Memory"的 iOS 应用程序崩溃?

标签 xamarin.ios

我的问题最初涉及从磁盘加载的字符串和我的应用程序内存不足的问题,但有一种更简单的方法可以使其崩溃,我不明白为什么。运行下面的代码,它会在几秒钟内死掉(iPad 4.2)。
理论上它应该永远运行。没有保留对大 StringBuilder 的引用,它会立即设置为 NULL。
如果我在 Instruments 中观看它,经过几次循环后内存会上升到 160MB,并且应用程序会死掉。为什么不释放内存?
每个循环增加大约 10MB 的内存......

一种想法是 GC 无法跟上,但 Thread.Sleep() 中的延迟有多大并不重要 - 最终,内存将消失。

该测试可能看起来很学术,但我遇到了崩溃的真实应用程序的问题。它有一个方法可以从 WebService 请求中获取(巨大的)字符串,将该字符串转换为 XmlDocument 并解析它(将某些内容存储到 DB)。然后该方法退出但内存保持高位。如果我再次执行相同的方法(大约一个小时后!),应用程序将死掉。为什么内存仍然分配?

public override bool FinishedLaunching ( UIApplication app, NSDictionary options )
        {
            Thread oThread = new Thread ( DoIt );
            oThread.Start (  );

            return true;
        }

        public void DoIt ()
        {
            using(var o = new NSAutoreleasePool())
            {
                while(true)
                {
                    StringBuilder oSB = new StringBuilder();
                    for(int i = 0; i < 800000; ++i)
                    {
                        oSB.Append("1234567890");
                    }
                    oSB = null;
                    Thread.Sleep(1000);
                }
            }
        }

EDIT :我注意到如果我改变 Do() 方法,如下所示,内存保持稳定。它上升了一段时间,然后 GC 开始并清理它。如果我在创建 NSString 对象后添加一个 s.Dispose(),内 stub 本不会增加。
所以这似乎是 .NET 字符串类的问题。
public void DoIt ()
            {
                using(var o = new NSAutoreleasePool())
                {
                                StringBuilder oSB = new StringBuilder();
                    for(int i = 0; i < 800000; ++i)
                    {
                        oSB.Append("1234567890");
                    }
                    while(true)
                    {
                            NSString s = new NSString(oSB.ToString());  
                        Thread.Sleep(1000);
                    }
                }
            }

最佳答案

StringBuilder 在每次迭代时在内部分配新的更大的数组(它的大小可能加倍)。最终,您将得到一个碎片化的堆。

关于xamarin.ios - 为什么此代码会导致 "Out Of Memory"的 iOS 应用程序崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4997276/

相关文章:

Xamarin.iOS 生成错误 System.IO.FileNotFoundException

android - 进入应用前台调用特定代码

iphone - 选择 WiFi 网络

Xamarin.forms webview 自动高度与内容

c# - 获取 UIControl Xamarin iOS 的名称

objective-c - 您如何绑定(bind)或调用 Foundation 函数?

.net - System.ExecutionEngineException : Attempting to JIT compile method System. Threading.Interlocked:Exchange

ios - 从 IntPtr 句柄获取 Xamarin.iOS NSObject(新的或缓存的)

iphone - 结合 UIAlertViewStyleLoginAndPasswordInput 与 UIKeyboardTypeEmailAddress

xamarin.ios - UIActivityIndi​​catorView.StartAnimating 重写 UIActivityIndi​​catorView.Hidden 绑定(bind)