【问题标题】:Does Immortal Object really exist?不朽之物真的存在吗?
【发布时间】:2016-08-23 13:08:28
【问题描述】:

在这篇文章中:Xamarin - Use Weak References to Prevent Immortal Objects 它表示如果两个对象相互强引用,它们将成为不朽的,这意味着 GC 无法收集它们,即使应用程序不再使用这些对象。

但是,在这 2 个 SO 讨论中:

Garbage collector and circular reference

Circular References Cause Memory Leak?

似乎循环引用可以被 GC 处理,只要对象不再被应用程序使用。

我有什么误解吗? Java 的 GC 在 Android 上的行为是否不同?我真的很困惑。 任何 cmets 都适用。谢谢!

【问题讨论】:

  • 如果您想了解 Android 垃圾收集器,为什么要链接到 MS .Net 上的两个讨论?你问的是哪个? .net 还是 android?对于 Android,How to Leak a Context
  • 那篇文章对我来说显然是不正确的,.NET GC 总是作为跟踪 GC 实现的,据我所知,它不会泄漏循环。
  • @Asik 与 Java 相同。这篇文章似乎假设 GC 基于引用计数,而 Java 或 .NET 并非如此。
  • @ElliottFrisch,之所以把两个dot Net讨论链接起来是因为那篇文章来自微软子公司Xamarin,它使我们能够在Android和IOS上使用dot Net。

标签: java c# android xamarin garbage-collection


【解决方案1】:

我做了一些研究,想回答我自己的问题。以下是一些发现:

  • 在 Java 和 C# 世界中,循环引用都不是问题。 GC 可以很好地处理。因此,对于 Xamarin Android, 文章不相关且具有误导性。但是,该文章列在跨平台...
  • 在 Obj-C 或 Swift 世界中,它们使用引用计数。和圆形 引用确实会导致内存泄漏。所以在 Xamarin.IOS 我们需要 小心点。 更新:感谢 PeterDuniho 的评论,准确地说,对于 Xamarin.IOS,托管世界由 Mono 管理,我们不必担心圈子。但是如果两个原生对象相互强引用,它们就会变得不朽......???

我想就是这样。链接有关此主题的一些参考资料:

【讨论】:

  • “所以在 Xamarin.IOS 中我们需要注意这一点” -- 如果您在 Xamarin 下运行的托管代码直接使用 iOS 内存分配器,那么您会这样做。但事实并非如此。 Xamarin 是托管代码和操作系统之间的一层;您的代码使用 Mono 内存管理系统,因此纯托管对象的行为与其他平台上的相同。 iOS 内存系统发挥作用的唯一地方是当您使用或扩展本机/对等对象时,托管引用本身不会影响这一点(但当然,您总是需要处置一次性对象,就像在普通 .NET 中一样代码)。
【解决方案2】:

Xamarin is based on Mono,它本质上是(现在)独立的 .NET 实现。和 .NET 一样,它基于可访问性,而不是引用计数或存在性来进行垃圾收集。 (Java GC 系统也是如此,但由于 Xamarin 不是基于 Java,这不是重点。)

两个相互引用但在程序中无法访问的对象有资格进行垃圾回收。无需使用弱引用来解决这种情况,因为一旦“根”引用无法访问两个对象,就会收集对象。

换句话说,您正在查看的文章显然是不正确的。事实上,使用弱引用可能会导致其他问题,因为保持对象活动变得更加复杂,从而更容易将错误写入代码中。令我惊讶的是,Xamarin 网站本身会出现这样的错误信息。

【讨论】:

    【解决方案3】:

    从您的问题中我不确定您关心什么语言或环境,但是在 Java 中,没有您描述的那种“不朽的对象”。 Java 垃圾收集不是基于引用计数:它基于根的可达性。由于应用程序中的其他任何地方都没有引用您的两个对象,因此它们有资格进行垃圾回收。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      相关资源
      最近更新 更多