【发布时间】:2016-08-21 16:57:09
【问题描述】:
我正在阅读由reducing referenced instances 撰写的关于帮助 GC 更好地执行的 Xamarin.Android 垃圾收集文档。
该部分开头说:
每当在 GC 期间扫描 Java.Lang.Object 类型或子类的实例时,也必须扫描该实例引用的整个对象图。对象图是“根实例”引用的对象实例的集合,加上根实例所引用的所有内容,递归地。
...我明白了。
然后它会显示一个继承自标准 Activity 类的自定义类。这个自定义活动类有一个字段,它是一个字符串列表,在构造函数中初始化为具有 10,000 个字符串。据说这很糟糕,因为在 GC 期间必须扫描所有 10,000 个实例的可达性。我也明白。
我不清楚的部分是推荐的修复:它说应该将List<string> 字段移动到另一个不继承自Java.Lang.Object 的类,然后应该引用该类的实例活动就像之前引用的列表一样。
我的问题:当实例总数仍然是 10,000 并且开头段落说由于过程是递归的而最终将被扫描时,将字段更深地推入对象图中如何帮助 GC?
作为旁注,我还在阅读 (here) 关于 Mono 在 Android 上使用的 SGen GC 和对象图遍历过程被描述为从 GC 根开始的广度优先。这解释了一个包含 10,000 个项目的列表将如何在检查每个项目时导致更长的 GC 暂停,但仍然没有解释将该列表移入图表的更深处有何帮助,因为 GC 最终会在它深入图表时对其进行扫描。
【问题讨论】:
-
这里的想法是我们避免进行同行步行。否则,我们需要在这些对象上同时查找
managed和Java关系。您通常可以通过移动到static类和Activity派生类之外来根您的对象,因此它独立于对等点。我会说大多数时候,这不是主要问题,您应该正常编码。如果您随后分析您的应用程序并注意到 GC 瓶颈,您现在就知道该做什么了。即将这些类与消耗它们的对等对象分开。简而言之:在需要之前不要担心 -
@JonDouglas 感谢您的回复。您能否澄清一下“同行同行”的含义以及如何决定这样做或避免这样做?总的来说,我认为我们真的可以使用一篇文章来解释如何在 Xamarin Android 中创建对象和进行 GC,因为它的“两个 VM 并排工作”架构......清楚地说明应该有助于我们理解“ do a peer walk" 并可能帮助我们避免在此Xamarin Evolve 谈话中讨论的问题。
标签: android xamarin mono garbage-collection xamarin.android