问题描述
我来自 C++ 背景,我已经使用 C# 工作了大约一年.像许多其他人一样,我对为什么确定性资源管理没有内置在语言中感到困惑.我们有 dispose 模式,而不是确定性析构函数.人们开始怀疑通过他们的代码传播 IDisposable 癌症是否值得付出努力.
I come from a C++ background and I've been working with C# for about a year. Like many others I'm flummoxed as to why deterministic resource management is not built-in to the language. Instead of deterministic destructors we have the dispose pattern. People start to wonder whether spreading the IDisposable cancer through their code is worth the effort.
在我偏向 C++ 的大脑中,使用带有确定性析构函数的引用计数智能指针似乎是垃圾收集器的一大进步,垃圾收集器需要您实现 IDisposable 并调用 dispose 来清理您的非内存资源.诚然,我不是很聪明......所以我问这个纯粹是为了更好地理解为什么事情会这样.
In my C++-biased brain it seems like using reference-counted smart pointers with deterministic destructors is a major step up from a garbage collector that requires you to implement IDisposable and call dispose to clean up your non-memory resources. Admittedly, I'm not very smart... so I'm asking this purely from a desire to better understand why things are the way they are.
如果 C# 被修改为:
What if C# were modified such that:
对象被引用计数.当一个对象的引用计数变为零时,会在该对象上确定性地调用资源清理方法,然后将该对象标记为进行垃圾回收.垃圾收集发生在未来某个不确定的时间,此时内存被回收.在这种情况下,您不必实现 IDisposable 或记得调用 Dispose.如果你有非内存资源要释放,你只需实现资源清理功能.
Objects are reference counted. When an object's reference count goes to zero, a resource cleanup method is called deterministically on the object, then the object is marked for garbage collection. Garbage collection occurs at some non-deterministic time in the future at which point memory is reclaimed. In this scenario you don't have to implement IDisposable or remember to call Dispose. You just implement the resource cleanup function if you have non-memory resources to release.
- 为什么这是个坏主意?
- 这会破坏垃圾收集器的目的吗?
- 实现这样的事情是否可行?
从目前的评论来看,这是一个坏主意,因为
From the comments so far, this is a bad idea because
- 没有引用计数,GC 更快
- 在对象图中处理循环的问题
我认为第一个是有效的,但第二个使用弱引用很容易处理.
I think number one is valid, but number two is easy to deal with using weak references.
速度优化是否比你的缺点更重要:
So does the speed optimization outweigh the cons that you:
- 可能无法及时释放非内存资源
- 可能过早释放非内存资源
如果您的资源清理机制是确定性的并且是语言内置的,那么您可以消除这些可能性.
If your resource cleanup mechanism is deterministic and built-in to the language you can eliminate those possibilities.
推荐答案
Brad Abrams 发布 一封来自 Brian Harry 的电子邮件,在 .Net 框架的开发过程中编写.它详细说明了未使用引用计数的许多原因,即使早期的优先事项之一是保持与使用引用计数的 VB6 的语义等价.它研究了一些可能性,例如对某些类型进行引用而不对其他类型进行计数(IRefCounted
!),或者对特定实例进行引用计数,以及为什么这些解决方案都不被认为是可接受的.
Brad Abrams posted an e-mail from Brian Harry written during development of the .Net framework. It details many of the reasons reference counting was not used, even when one of the early priorities was to keep semantic equivalence with VB6, which uses reference counting. It looks into possibilities such as having some types ref counted and not others (IRefCounted
!), or having specific instances ref counted, and why none of these solutions were deemed acceptable.
因为[资源问题管理和确定性定稿]就是这样一个我要尝试的敏感话题在我的尽我所能解释.我为...道歉邮件的长度.前 90%这封邮件试图说服你这个问题真的很难.在最后一部分,我会谈谈事情我们正在尝试做,但您需要第一部分要了解我们为什么查看这些选项.
Because [the issue of resource management and deterministic finalization] is such a sensitive topic I am going to try to be as precise and complete in my explanation as I can. I apologize for the length of the mail. The first 90% of this mail is trying to convince you that the problem really is hard. In that last part, I'll talk about things we are trying to do but you need the first part to understand why we are looking at these options.
...
我们最初是从假设解决方案将采取自动参考的形式计数(所以程序员不能忘记)加上一些其他的东西检测和处理周期自动地....我们最终得出的结论是这是行不通的一般情况.
We initially started with the assumption that the solution would take the form of automatic ref counting (so the programmer couldn't forget) plus some other stuff to detect and handle cycles automatically. ...we ultimately concluded that this was not going to work in the general case.
...
总结:
- 我们觉得解决循环问题很重要不强迫程序员了解、追踪和设计围绕这些复杂的数据结构问题.
- 我们希望确保我们拥有高性能(速度和工作集)系统和我们的分析表明使用引用计数对于系统中的每一个对象不会让我们实现这一目标目标.
- 出于多种原因,包括作曲和选角问题,没有简单的透明只有这些对象的解决方案需要对其进行引用计数.
- 我们选择不选择提供确定性的解决方案完成单个语言/上下文,因为它抑制与其他语言互操作导致类库分叉通过创建特定于语言的版本.
- We feel that it is very important to solve the cycle problem without forcing programmers to understand, track down and design around these complex data structure problems.
- We want to make sure we have a high performance (both speed and working set) system and our analysis shows that using reference counting for every single object in the system will not allow us to achieve this goal.
- For a variety of reasons, including composition and casting issues, there is no simple transparent solution to having just those objects that need it be ref counted.
- We chose not to select a solution that provides deterministic finalization for a single language/context because it inhibits interop with other languages and causes bifurcation of class libraries by creating language specific versions.
这篇关于为什么 C# 中没有引用计数 + 垃圾回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!