屏幕截图显示分配 - 不是内存泄漏。您可以要求 Instruments 跟踪泄漏,即没有找到对分配内存的引用。
但是,如果没有更多数据,就不可能说这些是否正常。我们至少需要知道分配来自哪里?Instruments 可以告诉您有关每个分配的更多详细信息。尝试向下钻取每个 heapshot 下的树,以查看分配的来源。
类似的情况通常是由于缓存造成的——这在每个级别都完成了。在应用程序代码之外,您会注意到 iOS 和它的框架进行缓存(例如图像、webkit ...)。
Mono 本身进行缓存,并且还使用在需要时会增长的内存池。将显示分配(即使已释放),但它不是泄漏 - 释放时,如果可能(例如大小),内存将被重用。
当然,它也可能是一个错误(在应用程序、任何框架、单点触控、iOS 中)。给定时间,如果应用程序发生在错误的位置(例如,运行循环的一部分、处理通知......),一个小的泄漏就足以使应用程序崩溃。只有找到分配的来源以及它们是否是重复分配(来自同一来源)才能告诉您这些分配的重要性。
编辑(更多)
所以昨晚我用自己的应用程序做了一个实验。下面的屏幕截图显示了 13 小时 45 分钟内的堆增长。
在前 4 小时 (1-13) 中,应用程序处于前台。最后一部分 (14) 应用程序在后台(晚上屏幕关闭)。记录在#14 之后也停止了,所以这个数字没有机会随着时间的推移而下降。
我的应用程序更大(初始基线为 5MB),启动后我没有使用它。一旦我知道初始化完成(它正在加载一个相当大的 80MB 数据库),我的第一个“标记堆”就完成了。OTOH 还监听网络事件,使用NSNetServiceBrowser
回调到托管代码(没有任何视觉线索)。
展开 Heapshot #1 显示单个对象,48 字节,堆栈跟踪以_ZL13_cache_mallocm
, cache_fill
, lookupMethod
, _class_lookupMethodAndLoadCache3
... 结尾,在调用者中没有显示我的应用程序或单声道。
展开 Heapshot #2 显示了四个对象,前两个在其堆栈跟踪中带有CA::Render::Encoder::ObjectCacche::invalidate(...)
和。CGNotificationCenterPostNotification
第三个带有_cache_addForwardEntry
,第四个看起来像 Heapshot #1 但是,就像第三个一样,它来自_XReceivedStatusBarDataAndAction
(不是我的应用程序或 monotouch 直接完成的事情)。
展开 Heapshot #3 显示 10 个对象......列出它们有点长,但它们都在同一个_XReceivedStatusBarDataAndAction
调用下。
扩展 heapshot #4 时的模式相同。
Heapshot #5 有一个区别(共 11 个),其中分配来自调度队列 (_xpc_connection_init),但没有可见的托管 (app) 或 mono[touch] 堆栈帧。
扩展堆 #6、#7、#8 时的模式相同(与 #3 相同)。
堆 #9 为空(未分配)。
Heapshot #10, #11 和 #3 一样。
Heapshot #12 也是空的。
Heapshot #13 与 #3 非常相似,但它也缓存相同的图像,并且在收到通知时发生CA::Render::Image::caches_encoding()
另一个_cache_fill
+ (不是托管的或下面的 MT 堆栈帧)。其他一些分配与通知有关。lookUpMethod
_significantTimeChange
UIApplicationMain
Heapshot #14 主要是关于通知(可能被告知它将进入后台)。还有一些_cache_fill
分配。
这是 iOS 问题、MonoTouch 问题还是其他问题?
上面没有任何内容指向 MonoTouch 甚至我的应用程序。OTOH 我没有将它与 ObjC 应用程序进行比较(可能没有时间这样做),但我相信你会看到一些非常接近的东西 - 取决于正在使用的 API/服务(并且执行相同操作的应用程序应该显示相同)分配)。
就像我在 YMMV 之前所说的那样,泄漏(或意外的内存保留)通常是特定于 API 的。如果您在仪器会话中发现奇怪的堆栈跟踪,请填写关于它们的错误报告(给 Xamarin 或 Apple,取决于堆栈跟踪),以便可以分析和修复它们(如果有错误)。
创建 24/7 全天候 iPad 应用程序的计划是否现实?
至于 24/7 运行应用程序,我认为它可以完成 - 但它需要用户的合作(这可能是不现实的)。切换到另一个应用程序(主页按钮、手势)意味着您的应用程序不会在前台,Apple 可以终止任何后台应用程序以回收内存。例如,App X 内存不足,iOS 开始询问,然后杀死后台应用程序以满足前台应用程序。