【发布时间】:2014-10-21 09:00:45
【问题描述】:
过去 8 个月来,我们一直在使用 Xamarin iOS,并开发了一个具有许多屏幕、功能和嵌套控件的非平凡企业应用程序。我们已经完成了我们自己的 MVVM 架构、跨平台 BLL 和 DAL 作为“推荐”。我们在 Android 之间共享代码,甚至我们的 BLL/DAL 也用于我们的网络产品。
一切都很好,除了现在在项目的发布阶段,我们发现在基于 Xamarin iOS 的应用程序中到处都是不可修复的内存泄漏。我们已遵循所有“指南”来解决此问题,但现实情况是 C# GC 和 Obj-C ARC 似乎是不兼容的垃圾收集机制,目前它们在单点触控平台中相互叠加。
我们发现的现实是,对于任何非平凡的应用程序,本机对象和托管对象之间将发生并且经常发生硬循环。例如,在您使用 lambdas 或手势识别器的任何地方都非常容易发生这种情况。加上 MVVM 的复杂性,这几乎是一种保证。错过其中一种情况,整个对象图将永远不会被收集。这些图表会引诱其他物体进入并像癌症一样生长,最终导致 iOS 迅速无情地消灭。
Xamarin 的回答是对此问题毫无兴趣的推迟,并且不切实际地期望“开发人员应该避免这些情况”。仔细考虑这一点表明这是承认 垃圾收集在 Xamarin 中基本上被破坏了。
我现在意识到,在传统的 c# .NET 意义上,您并没有真正在 Xamarin iOS 中获得“垃圾收集”。您需要采用“垃圾维护”模式才能真正让 GC 移动并完成其工作,即使那样它也永远不会完美 - 非确定性。
我的公司投入了大量资金,试图阻止我们的应用崩溃和/或内存不足。我们基本上不得不明确地递归地处理所有可见的东西,并在应用程序中实施垃圾维护模式,只是为了阻止崩溃并拥有我们可以销售的可行产品。我们的客户是支持和宽容的,但我们知道这不可能永远保持下去。我们希望 Xamarin 有一个专门的团队来解决这个问题,并一劳永逸地解决这个问题。不幸的是,看起来不像。
问题是,我们的经验是用 Xamarin 编写的重要企业级应用程序的例外还是规则?
更新
查看 DisposeEx 方法和解决方案的答案。
【问题讨论】:
-
您对“垃圾收集基本上在 Xamarin 中被破坏”的参考在哪里?就个人而言,我认为你是例外而不是规则。我没有像你提到的任何记忆问题。我遇到的唯一与生产相关的问题是链接 SDK。
-
如果它是一个游戏应用程序,我不会这么惊讶,但对于“企业”应用程序,我很怀疑。让我们看看您的问题和解决方法的一些示例。
-
Herman,我完全同意你的看法,垃圾收集 IS 在 Xamarin.iOS/MonoTouch 上损坏。一年前我也有同样的经历,甚至建立了一个像你在这里发布的那样的“层次结构清理器”。我的应用程序是一个消费者应用程序,几乎有 ± 35 个控制器,我花了 3 个多月的时间才把内存弄出来。 Xamarin 工作人员中的某个人告诉我他们正在研究它,但又过了一年,我看不到任何进展,甚至样本都充满了这些反模式 lamdas。
标签: c# ios xamarin.ios garbage-collection xamarin