.Net vs Java 垃圾收集器
有谁知道Java和.Net垃圾回收器之间的主要区别吗?网络搜索没有发现太多,这是一个在测试中出现的问题。
有谁知道Java和.Net垃圾回收器之间的主要区别吗?网络搜索没有发现太多,这是一个在测试中出现的问题。
区别在于CLR(.Net)GC和JVM GC之间,而不是语言本身。两者都可能会发生变化,并且其行为规范会松散,以允许在不影响程序正确性的情况下进行更改。
有一些历史差异,主要是由于.Net的设计借鉴了java(以及其他基于gc的平台)的演变。在下文中,不要假设.Net在某种程度上更优越,因为它从一开始就包含功能,它只是后来的结果。
一个值得注意的公开可见的区别是,MS GC暴露了其代际性质(通过GC api),这可能会在一段时间内保持真实,因为这是基于大多数程序表现出的行为而采取的明显方法:大多数分配都是非常短暂的。
最初的JVM没有代际垃圾回收器,尽管这个功能被迅速添加。由SunOracle和其他人实施的第一代收集器往往是Mark和Sweep。人们意识到,标记扫描紧凑方法将带来更好的内存局部性,从而证明额外的复制开销是合理的。CLR 运行时首次出现此行为。
SunOracle和微软的GC实现“精神”之间的区别在于可配置性。
Sun's提供了大量的选项(在命令行)来调整GC的各个方面或在不同模式之间切换。许多选项都是 -X 或 -XX,以指示它们在不同版本或供应商之间缺乏支持。相比之下,CLR几乎没有可配置性;您唯一真正的选择是使用服务器或客户端收集器,分别针对吞吐量和延迟进行优化。
两家公司(和开源实现)都在进行GC策略的积极研究,最新的GC实现中使用的当前方法是每线程伊甸园区域(改善局部性并允许伊甸园集合可能不会引起完全暂停)以及预紧张方法,这些方法试图避免将某些分配放入伊甸园生成中。
这只是为了补充ShuggyCoUk的出色答案。.NET GC 还使用所谓的大型对象堆 (LOH)。CLR 在 LOH 上预分配一堆对象,所有至少 85000 字节的用户分配对象也会在 LOH 上分配。此外,由于一些内部优化,LOH上也分配了1000个或更多的元素。double[]
LOH 的处理方式与代际堆的处理方式不同:
malloc
我不知道JVM是否有类似的东西,但它是关于如何在.NET中处理内存的基本信息,所以希望你发现它很有用。