为什么没有引用计数+垃圾收集在C#中? [英] Why no Reference Counting + Garbage Collection in C#?

查看:148
本文介绍了为什么没有引用计数+垃圾收集在C#中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自C ++背景,我一直在使用C#大约一年。像许多其他人一样,我为什么决定性的资源管理不是内置于语言中而感到沮丧。我们有了处置模式,而不是确定性的析构函数。 人们开始怀疑是否通过他们的代码传播IDisposable癌症是值得的。

在我的C ++偏见的大脑中,似乎使用引用计数的智能指针与确定性析构函数是垃圾回收器的一大进步,它要求您实现IDisposable并调用处理清理你的非内存资源。诚然,我不是很聪明......所以我纯粹是从一种渴望中去问这个问题,以便更好地理解为什么事情是这样的。



如果C#被修改为:



对象是引用计数。当对象的引用计数变为零时,将在对象上确定性地调用资源清理方法,然后将该对象标记为垃圾回收。垃圾收集发生在未来的某个非确定性时间,在这个时间点回收内存。在这种情况下,您不必实现IDisposable或记得调用Dispose。如果您有非内存资源可以发布,您只需实施资源清理功能。




  • 为什么这是一个坏主意?

  • 是否会破坏垃圾回收器的功能?

  • 执行这样的事情是否可行?



编辑:
从目前的评论来看,这是一个糟糕的主意,因为


  1. GC没有引用计数就更快了

  2. 处理对象图中的周期问题

我认为第一是有效的,但第二很容易处理使用弱引用。



所以速度优化胜过你的缺点:


  1. 可能无法及时释放非内存资源

  2. 可能会很快释放非内存资源

如果您的资源清理机制是确定性的并且内置于该语言中,您可以消除这些可能性。 b $ b

解决方案

Brad Abrams发布了来自Brian Harry的一封电子邮件,在.Net框架开发过程中编写的。它详细介绍了很多未使用引用计数的原因,即使早期的优先事项之一是与使用引用计数的VB6保持语义等价。它研究了一些可能性,比如让某些类型的ref被计数,而不是其他类型( IRefCounted !!),或者计算具体实例,以及为什么没有这些解决方案被认为是可接受的。 / b>


因为[资源
管理和确定性
定稿问题]就是这样一个
敏感话题我会尝试以
为准,并尽我所能在
解释中做到精确和完整。我为
邮件的长度道歉。这封邮件的前90%b $ b试图说服你
这个问题真的很难。在最后一部分的
中,我会谈论我们正在尝试做的事情
,但您需要
第一部分来理解为什么我们在
看这些选项。 p>

...



我们最初从
假设开始,解决方案为
采取自动ref
计数的形式(所以程序员不能
忘记)加上一些其他的东西到
自动检测和处理循环
。 ...我们最终得出结论认为,
这不适用于
的一般情况。



.. 。



总结:


  • 我们认为这对于<解决循环问题
    不会迫使程序员去
    理解,追踪并设计
    这些复杂数据结构
    的问题。
  • 我们希望确保我们具有高性能(速度和
    工作集)系统,而我们的分析
    显示使用引用计数
    用于每个单个对象系统
    不会允许我们实现此
    目标

  • 由于各种原因(包括合成和铸造
    问题) 没有简单的透明
    解决方案,只需将那些需要它计入的对象
    计入

  • 我们选择不选择提供 de的解决方案由于它禁止
    interop
    与其他语言和
    导致类库的分叉
    通过创建语言特定的$ $

    $ b完成了单个
    语言/ b $ b版本。



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.

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.

What if C# were modified such that:

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.

  • Why is that a bad idea?
  • Would that defeat the purpose of the garbage collector?
  • Would it be feasible to implement such a thing?

EDIT: From the comments so far, this is a bad idea because

  1. GC is faster without reference counting
  2. problem of dealing with cycles in the object graph

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:

  1. may not free a non-memory resource in a timely manner
  2. might free a non-memory resource too soon

If your resource cleanup mechanism is deterministic and built-in to the language you can eliminate those possibilities.

解决方案

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.

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.

...

In summary:

  • 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#中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆