垃圾收集前是否清除了内存?

与同事进行了这次讨论。 当c#或java垃圾等语言收集诸如字符串之类的对象,将它们返回堆中时,它们是否也清除了这个内存块,例如用0或1覆盖?

我的假设是块按原样返回,除非使用诸如securestring和finalize重载之类的类来阻止块。

实际上,不,这不会发生。 覆盖你刚刚释放的内存需要时间,所以会有性能损失。 像SecureString这样的“安全”对象只是擦拭自己 ,而不是依靠GC。

更广泛地说,它在很大程度上取决于该特定语言的特定实现。 假定存在GC的每种语言(如C#)都规定了有关垃圾收集应该如何以及何时发生的不同规则。

为了获得您的C#示例,C#规范不要求在被释放后覆盖对象,并且它也不禁止它:

最后,在对象符合收集条件后的某个时间,垃圾收集器释放与该对象关联的内存。

§3.9C #5.0语言规范

如果稍后将内存分配给引用类型,则您将拥有一个执行自定义初始化的构造函数。 如果稍后将内存分配给值类型,则在开始读取内存之前它会被清零:

初始化为默认值通常通过让内存管理器或垃圾收集器在分配使用之前将内存初始化为所有位为零来完成。 因此,使用all-bits-zero来表示空引用是很方便的。

§5.2C #5.0语言规范

此外,至少有两个C#实现 – 微软的实现和Mono的实现,所以只说“C#”不够具体。 每个实现可能决定覆盖内存(或不覆盖)。

据我所知,没有一个垃圾收集器实际上用0或任何数字擦除内存。 C#和Java垃圾收集器从未使用的对象中回收内存并将其标记为可用。 SecureString在完成时擦除自身,但这不是GC的事情。