与同事进行了这次讨论。当c#或java垃圾等语言收集诸如字符串之类的对象,将它们返回堆中时,它们是否也清除了这个内存块,例如用0或1覆盖?
我的假设是块按原样返回,除非使用诸如securestring和finalize重载之类的类来阻止块。
答案 0 :(得分:3)
实际上,不,这不会发生。覆盖你刚刚释放的内存需要时间,因此会有性能损失。像SecureString这样的“安全”对象是just wiping themselves,不依赖于GC。
更广泛地说,它在很大程度上取决于该特定语言的特定实现。假定存在GC的每种语言(如C#)都规定了有关垃圾收集应该如何以及何时发生的不同规则。
要采用C#示例,C#规范不要求在释放后覆盖对象,也不要禁止它:
最后,在对象符合收集条件后的某个时间,垃圾收集器释放与该对象关联的内存。
如果稍后将内存分配给引用类型,您将拥有一个执行自定义初始化的构造函数。如果稍后将内存分配给值类型,则在开始读取之前它会被清零:
初始化为默认值通常通过让内存管理器或垃圾收集器在分配使用之前将内存初始化为所有位为零来完成。因此,使用all-bits-zero表示空引用很方便。
此外,至少有两个C#实现 - 微软的实现和Mono的实现,所以只说“C#”不够具体。每个实现可能决定覆盖内存(或不覆盖)。
答案 1 :(得分:2)
据我所知,并不是一个垃圾收集器实际上用0或任何数字擦除内存。 C#和Java垃圾收集器从未使用的对象中回收内存并将其标记为可用。 SecureString
在完成时擦除了自己,但这不是GC的事情。