.NET垃圾回收器真的是一个垃圾回收器吗?

5
我正在开发一个实现IDisposable接口的项目。在这个项目中,我发现自己对垃圾回收器的了解可以被描述为非常少。因此,我开始阅读一些文档,最终在MSDN上找到了《垃圾回收基础知识》文章
你必须明白,此时我一直认为垃圾回收器是在处理程序产生的废物的下水道工人。因此,我很惊讶地读到以下片段
“在CLR初始化垃圾回收器之后,它分配了一个内存段来存储和管理对象。”
文章的下一段中,指出:
“为了保留内存,垃圾回收器调用Win32 VirtualAlloc函数,并为托管应用程序一次性保留一个内存段。垃圾回收器还根据需要保留段,并通过调用Win32 VirtualFree函数(在清除其中任何对象后)将段释放回操作系统。”
如果我理解正确的话,GarbageCollector实际上是.NET程序的MemoryManager!
我知道,它仍然会收集垃圾。但这不就像把歌手称为麦克风持有者吗?当然,这是真的,但你不会为此花钱去看他们演出。GarbageCollector显然做了更多事情,它几乎不公平地被称为垃圾收集器。
所以总之:
我理解得对吗?还是我完全错了?
如果我理解正确的话:为什么.NET开发人员称其为GarbageCollector?

4
+1表示“就像称呼歌手为麦克风持有者”一样。 - Daniel Hilgarth
4个回答

4
不仅是.NET,Java、C++、Objective-C等其他语言也使用相同的术语。它们确实管理内存,但主要是为了清理留下的垃圾。想一想,分配内存其实是一项相当琐碎的任务 - 主要是调用VirtualAlloc。真正的难点和科学在于清理进程使用的内存。.NET GC确实是一个高度调整的引擎,许多人花费了大量的精力优化GC以清理垃圾,例如处理内存中的固定对象、碎片堆、后台处理以避免影响性能等。所以你可以称之为MemoryManager,但公平地说,它的真正强项是收集垃圾。

3
您是正确的,垃圾收集器本质上是一种内存管理器。
如果您考虑到垃圾收集需要发生,那么最实用的方法就是让垃圾回收机制和内存分配机制(以及紧凑垃圾收集器的情况下的引用解析策略)非常密切相关。
原因在于,垃圾收集器需要执行大量的簿记才能运行。为了可靠地执行该簿记,它需要了解发生的分配等信息。最明显的方法是垃圾收集器提供自己的内存分配例程。这可以通过提供新的内存分配器接口来完成,该接口与语言提供的标准接口不同(并可能利用它,如Marco在评论中提到的那样),或者通过拦截并基本替换语言的标准内存分配器来完成。
无论如何,所有内存管理器都需要提供某种类型的内存分配机制,因此这并不是它们之间的区别所在。但是,只有少数内存管理器可以自动收集垃圾,因此我们在命名这些内存管理器时会专注于这一点。实际上,“垃圾收集器”真正意味着“垃圾收集内存管理器”。
现在它的常用名称可能确实有点误导,但这并不是.NET开发人员想出来的。这样的内存管理器一直被称为垃圾收集器,可能早在Lisp概念的第一次存在时就已经如此。我想这是出于历史原因而保留下来的。

1
我想理论上GC可以调用memmanager为自己分配内存块。它不一定要调用操作系统。这也使得非托管代码能够直接调用memmanager(当然不会被GC处理)。 memmanager的块映射可以在GC的根识别过程中使用。 - Marco van de Voort
@MarcovandeVoort 你说得对。我已经编辑过了,也加上了这个描述。 - Theodoros Chatzigiannakis

2
在.Net中,回收未使用的内存的实体被称为垃圾回收器,可能是因为自从20世纪50年代-60年代开始自动内存管理的想法就已经被称为垃圾收集器。
也许最初,管理内存分配的问题被认为是单独的问题,因为这对于手动内存管理也是必需的。更深层次的问题是如何检测程序不再使用的分配内存的哪些部分,“垃圾”,并释放它们以供重复使用。显然,如果您知道如何分配内存,那么您也可以将分配内存的责任交给GC,这样做会更容易。

0

基本上它是一个内存管理器,但同时也会删除未使用的对象以回收内存空间。在删除垃圾对象之后,它会对对象进行排序/排列,以便新对象将被创建在下一个内存位置。

我建议你阅读《CLR via C#》这本书,它对垃圾回收器有很好的解释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接