gpt4 book ai didi

c# - GC 会清理非事件但在范围内的引用所引用的对象吗?

转载 作者:行者123 更新时间:2023-11-30 13:55:11 24 4
gpt4 key购买 nike

我想知道我是否可以依靠 .NET 垃圾收集器来避免在这种情况下保留一堆额外的堆对象:

public static void Main(string[] args) {
var a = ParseFileAndProduceABigTreeObject(args[0]);
var b = WalkTheBigTreeObjectAndProduceSomeOtherBigObject(a);
var c = AThirdRoundOfProcessing(b);
Console.WriteLine(c.ToString());
}

在这里的每个阶段,需要理解的是每个方法返回的对象不包含对先前对象的引用,因此 b 不引用 a,并且c 不引用 ab

天真的 GC 实现会在程序的整个持续时间内保持 a 存在,因为它仍然可以通过 Main 方法的堆栈框架访问。

我想知道的是,我是否可以依靠 .NET 进行 active 分析并确定在执行第三行 (AThirdRoundOfProcessing) 时,a不再需要,必要时可以回收其内存?

我几乎可以肯定 .NET 至少有时会处理这样的情况,所以我的问题实际上是这样的:它是否足够一致让我依赖它,或者我应该假设它可能不会并采取措施让代码更万无一失? (例如,在这里,我可以将 a 设置为 null。)

P.S.:OpenJDK 怎么样,它能很好地处理它吗?

编辑:我可能不清楚。我知道,就标准而言,允许但不需要运行时收集 a。如果我在一个假想的运行时上运行我的代码,我只知道它是一致的,我将不得不忍受这种不确定性。但是,我的代码在最新版本的 Microsoft .NET 4 运行时上运行。我想知道的是该运行时是否可以执行此操作。运行时是实际代码,可以确切地知道它会做什么。也许外面有人知道这些知识并愿意分享。

最佳答案

您永远不能依赖 GC 来清理任何东西。永远不会要求在对象符合收集条件时立即清理它们。整个 IDisposable 模式的存在正是因为没有让 GC 清理资源的确定性方法。 GC 的强大之处在于它不必在资源的生命周期结束时立即清理资源。它可以自由地在需要时清理符合条件的资源,从而能够更有效地完成工作,而对何时需要清理给定资源几乎没有任何要求。

一旦运行时可以证明该对象永远不会从将来执行的代码中再次访问,该对象就有资格收集,因此在您的情况下,根据您的描述,那些对象有资格收集,但您不能期望在整个过程被拆除之前的任何时候它们实际上会被收集。

关于c# - GC 会清理非事件但在范围内的引用所引用的对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36508231/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com