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