我们正在与iPad应用程序中的内存泄漏作斗争,该应用程序必须足够稳定以便能够保持24/7全天候运行,因此,内存泄漏是无法容忍的。
作为一个简单的测试,我们使用“单一视图”模板创建了一个新的iPad MonoTouch项目,并使用iPad本身的仪器(iPad第三代,没有其他应用程序在内存中运行)执行它。
在乐器中,如果我们经常按下“标记记忆”按钮,它会不断地记忆。不多,但每隔一段时间就有一点:
应用程序实际上对我们一无所知,但显然正在执行分配内存的东西。
这是iOS问题,MonoTouch问题还是别的什么?
创建24/7 iPad应用程序的计划是否切合实际?我们担心当我们开始添加代码时,内存泄漏量也会升级。该应用程序可能会清楚地运行上面图像中的泄漏很长一段时间,但如果它上升,内存已满的截止日期将更快点击。
答案 0 :(得分:6)
屏幕截图显示了分配 - 而不是内存泄漏。您可以要求Instruments跟踪泄漏,即没有找到分配内存的参考。
然而,没有更多数据,如果那些正常是不可能的话。我们至少需要知道分配来自哪里?仪器可以告诉您每个分配的更多细节。尝试向下钻取每个快照下的树,以查看分配的来源。
由于缓存,类似的情况通常是 - 这是在每个级别完成的。在应用程序代码之外,您会注意到iOS及其框架正在进行缓存(例如图像,webkit ......)。
Mono本身可以进行缓存,还可以使用在需要时增长的内存池。将显示一个分配(即使释放),但它不是泄漏 - 当释放时,如果可能(例如大小)重新使用内存将被重用。
当然它也可能是一个bug(在应用程序中,任何框架,单声道触摸,iOS)。给定时间单个小泄漏足以使应用程序崩溃,如果它发生在错误的位置(例如运行循环的一部分,处理通知......)。只找到分配的来源以及它们是否是重复分配(来自同一来源)将告诉您这些分配有多重要。
编辑(更多)
所以我昨晚做了自己的应用实验。下面的屏幕截图显示了13小时45分钟的堆增长。
在前4个小时(1-13),应用程序处于前台。最后一部分(14)应用程序在后台(屏幕关闭了一夜)。录音也在#14之后停止,因此这个数字随着时间的推移没有机会下降。
我的应用程序更大(初始基线为5MB),并且在启动后我没有使用它。一旦我知道初始化完成(它正在加载quite large,80MB数据库),我的第一个“Mark Heap”就完成了。 OTOH listen to network events使用NSNetServiceBrowser
回调托管代码(没有任何视觉线索)。
扩展快照#1显示一个对象,48个字节,堆栈跟踪以_ZL13_cache_mallocm
,cache_fill
,lookupMethod
,_class_lookupMethodAndLoadCache3
结尾...我的一切都没有应用程序或单声道在呼叫者中显示得更高。
扩展快照#2显示了四个对象,前两个对象的堆栈跟踪中包含CA::Render::Encoder::ObjectCacche::invalidate(...)
和CGNotificationCenterPostNotification
。第三个是_cache_addForwardEntry
,第四个看起来像是快照#1,但是和第三个一样,它来自_XReceivedStatusBarDataAndAction
(不是我的应用程序或单音素直接完成的东西)。
扩展快照#3显示了10个对象...有点长,无法列出它们,但它们都在同一个_XReceivedStatusBarDataAndAction
调用下。
扩展快照#4时的相同模式。
快照#5有一个区别(11个中),其中分配来自调度队列(_xpc_connection_init),但没有可见的托管(app)或单个[触摸]堆栈框架。
扩展快照#6,#7,#8时的相同模式(如#3)。
快照#9为空(无分配)。
快照#10,#11喜欢#3。
快照#12也是空的。
快照#13主要与#3类似,但当收到CA::Render::Image::caches_encoding()
通知时(不管理),它也会缓存相同的图片,_cache_fill
和另一个lookUpMethod
+ _significantTimeChange
或UIApplicationMain
下面的MT堆栈帧。其他一些分配与通知有关。
快照#14主要是关于通知(可能被告知它将进入后台)。还有一些_cache_fill
分配。
这是iOS问题,MonoTouch问题还是别的什么?
上面没有任何内容指向MonoTouch甚至我的应用程序。 OTOH我没有将它与ObjC应用程序进行比较(并且可能没有时间这样做)但我相信你会看到一些非常接近的东西 - 取决于所使用的API /服务(并且做同样事情的app应该显示相同的东西)分配)。
就像我在YMMV之前所说的那样,泄漏(或意外的内存保留)通常是API特定的。如果您在仪器会话中发现奇怪的堆栈跟踪,请填写错误报告(Xamarin或Apple,具体取决于堆栈跟踪),以便对它们进行分析和修复(如果有错误)。
计划创建一个24/7的iPad应用程序是否真实?
至于24/7运行应用程序,我认为可以做到 - 但它需要用户的合作(这可能是不现实的)。切换到另一个应用程序(主页按钮,手势)意味着您的应用程序将不在前台,Apple可以杀死任何后台应用程序以回收内存。例如。 App X内存不足,iOS开始询问,然后查杀后台应用以满足前台应用。