.NET与Java垃圾收集器

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

有谁知道Java和.Net垃圾收集器之间的主要区别吗?网络搜索没有透露太多,这是一个在测试中出现的问题。

提问于
用户回答回答于

这只是为了增加ShuggyCoUk的出色答案。.NET GC也使用大对象堆(LOH)。CLR在LOH上预分配了一堆对象,并且所有用户分配的至少85000字节的对象也分配在LOH上。此外,double[]由于一些内部优化,在LOH上也分配了1000个或更多元素。

LOH的处理方式与世代堆不同:

  • 它只在全面收集时清理干净,并且不会像世代堆积物那样被压缩。
  • 来自LOH的分配是通过一个空闲列表完成的,就像malloc在C运行时中处理一样,而来自代码堆的分配基本上是通过在第0代中移动一个指针来完成的。

我不知道JVM是否有类似的东西,但它是关于如何在.NET中处理内存的重要信息,所以希望您能发现它很有用。

用户回答回答于

CLR(.Net)GC和JVM GC之间的区别不在于语言本身。两者都可能会发生变化,并且其行为规范会变得松散,以​​便在不影响程序正确性的情况下对其进行更改。

有一些历史性的差异很大程度上是由于.Net是通过java(和其他基于gc的平台)的发展而设计的。在下面的内容中,不要以为.Net在某种程度上更好,因为它从一开始就包含了功能,这只是后来的结果。

一个显着的公众可见的区别是MS GC揭示其代代性质(通过GC api),这可能会保持一段时间,因为根据大多数程序展现的行为,这是一个明显的方法:大多数分配非常短命。

最初的JVM没有世代垃圾回收器,尽管这个功能很快被添加。Sun Oracle和其他公司实施的第一代收集器往往是Mark和Sweep。人们意识到,标记扫描 - 紧凑方法会导致更好的内存位置,从而证明额外的复制开销。CLR运行时首次出现这种行为。

Sun Oracle和Microsoft的GC实施“精神” 之间的区别在于可配置性。

Sun提供了大量选项(在命令行中)来调整GC的各个方面或在不同模式之间切换。许多选项都是-X或-XX,表示它们在不同版本或供应商中缺少支持。相比之下,CLR几乎没有可配置性; 您唯一真正的选择是使用服务器或客户端收集器,分别优化吞吐量和延迟。

GC战略的积极研究正在两家公司(以及开源实施中)中进行,最新GC实施中使用的当前方法是每个线程伊顿区域(改善局部性并允许伊甸园收集可能不会导致完全暂停)作为试图避免将某些分配放入伊甸园一代的前期工作方法。

扫码关注云+社区