Xamarin.ios 手动调用垃圾收集器的成本有多高?

Xamarin.ios 手动调用垃圾收集器的成本有多高?,xamarin.ios,garbage-collection,xamarin,Xamarin.ios,Garbage Collection,Xamarin,我正在优化我的应用程序的内存消耗,刚刚发现GC(sgen)有时非常懒惰,所以它没有清理到目前为止已经处理了很长时间的所有东西。我甚至不知道这些东西是否会被收集,这对于所有指向本机资源的指针(UIImage等)来说尤其重要 因此,我开始在应用程序中的某些点手动调用GC,例如在弹出或关闭控制器时 GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); 我知道这需要花费一些时间来完成,但是我还有其他的缺点需要考虑吗?< / P >

我正在优化我的应用程序的内存消耗,刚刚发现GC(sgen)有时非常懒惰,所以它没有清理到目前为止已经处理了很长时间的所有东西。我甚至不知道这些东西是否会被收集,这对于所有指向本机资源的指针(UIImage等)来说尤其重要

因此,我开始在应用程序中的某些点手动调用GC,例如在弹出或关闭控制器时

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

我知道这需要花费一些时间来完成,但是我还有其他的缺点需要考虑吗?< / P > <是的,还有一些其他的缺点。

即使调用GC.Collect,也无法确保您认为已经消失的对象实际上已经消失。可能存在对托管代码或非托管代码中看不到的对象的引用

就GC而言,像“UIImage”这样的对象只占用很少的字节,您可能会加载几千个这样的对象并消耗兆字节的RAM,但就GC所知,只有几KB的数据

这是因为GC不知道这些无辜的UIImage对象实际上指向非托管空间中的一个巨大内存块

在.NET上也会发生这种情况。当您停止使用某些珍贵资源时,您应该立即将其归还给所有者,而不是依赖GC来收集对象,因为GC真的不知道可爱的小对象有多重要

这些资源通常是图像(它们消耗大量RAM)、网络连接(这些连接的数量有限)、数据库连接(有时每个连接可能收费)、文件(有限数量的句柄)等等

它们实现IDisposable接口,您应该在使用完它们后立即调用Dispose()

UIImage就是其中之一。您需要主动调用这些对象上的Dispose

也就是说,在Xamarin.iOS中,NSObject子类的所有内容都是IDisposable。这就是我们所采用的模式,它强制放弃对非托管资源的所有权,即使其中许多资源不是很昂贵(NSString、NSUrl等等)


最好的策略是运行探查器,识别您的大而胖的对象,并确保尽早处理它们。

关于
IDisposable
和在正确的时间调用
dispose()
,对我来说看起来更干净了!我做得很重,但它不能立即释放内存。特殊的MonoTouch体系结构可能有什么问题,它在本机Objective-C环境上运行垃圾收集,本机Objective-C环境是引用计数的。
Dispose()
Dispose()
是一种通知托管(Mono、.NET)对象释放其持有的非托管(iOS、Android、Windows)资源的方法。这不会立即释放Mono使用的内存,但会释放本机UIImage,friendsI将进一步分析它,并与仪器进行行为比较。谢谢你,欧根,你说得对。嗨,米格尔,谢谢你详细的回答。如果你知道我在过去几周里经历了什么。。。所以我想我知道的最多,我认为手动调用GC.Collect()会加快进程,这是对使用工具的分析会话的误解。