手动调用垃圾收集器有多贵?

asp*_*net 2 garbage-collection xamarin.ios xamarin

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

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

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
Run Code Online (Sandbox Code Playgroud)

我知道这需要一些时间才能完成,但是我还有其他的缺点需要考虑吗?

mig*_*aza 6

是的,还有其他一些缺点.

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

就GC而言,像"UIImage"这样的对象只占用少量字节,你可能会加载几千个这些对象并占用兆字节的RAM,但据GC所知,只有几KB的内存.数据.

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

这也发生在.NET上.有一些宝贵的资源,一旦你停止使用它们就应该返回给所有者,而不是依靠GC收集物体,因为GC真的不知道可爱的小物体有多重要.

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

那些实现了IDisposable接口,你应该在完成后立即调用Dispose().

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

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

最好的策略是运行探查器,识别你的胖,大物体,并确保尽早处理它们.