C# .Net 与 Java 垃圾收集器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/492703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:31:57  来源:igfitidea点击:

.Net vs Java Garbage Collector

c#javagarbage-collection

提问by Mike

Does anyone know the major differences between the Java and .Net garbage collectors? A web search has not revealed much, and it was a question that came up in a test.

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

回答by tobsen

I found this:

我找到了这个:

In the J2SE platform version 1.4.2 there were four garbage collectors from which to choose but without an explicit choice by the user the serial garbage collector was always chosen. In version 5.0 the choice of the collector is based on the class of the machine on which the application is started.

在 J2SE 平台版本 1.4.2 中,有四个垃圾收集器可供选择,但在用户没有明确选择的情况下,始终选择串行垃圾收集器。在 5.0 版中,收集器的选择基于启动应用程序的机器的类。

hereand this

这里和这个

Also just as the JVM manages the destruction of objects so also does the CLR via a Mark and Compact garbage collection algorithm

就像 JVM 管理对象的销毁一样,CLR 也通过 Mark 和 Compact 垃圾收集算法来管理对象的销毁

here

这里

I hope this helps...

我希望这有帮助...

回答by ShuggyCoUk

The difference is between the CLR (.Net) GC and the JVM GC rather than the languages themselves. Both are subject to change and the specification of their behaviour loose to allow this to be changed without it affecting the correctness of programs.

区别在于 CLR (.Net) GC 和 JVM GC 而不是语言本身。两者都可能发生变化,并且它们的行为规范松散,以允许在不影响程序正确性的情况下进行更改。

There are some historical differences largely due to .Net being designed with lessons from the evolution of the java (and other gc based platforms). In the following do not assume that the .Net one was in some way superior because it included functionality from the beginning, it is simply the result of coming later.

有一些历史差异主要是由于 .Net 是根据 java(和其他基于 gc 的平台)的演变而设计的。在下文中,不要假设 .Net 在某些方面更出色,因为它从一开始就包含了功能,这只是后来出现的结果。

A notable publicly visible difference is that the MS GC exposes its generational nature (via the GC api) this is likely to remain true for some time since this is an obvious approach to take based on the behaviour that most programs exhibit: Most allocations are extremely short lived.

一个显着的公开可见的差异是 MS GC 暴露了它的分代性质(通过 GC api)这可能会持续一段时间,因为这是基于大多数程序表现出的行为的一种明显的方法:大多数分配非常短暂的。

Initial JVM's did not have generational garbage collectors though this feature was swiftly added. The first generational collectors implemented by SunOracle and others tended to be Mark and Sweep. It was realized that a mark-sweep-compact approach would lead to much better memory locality justifying the additional copying overhead. The CLR runtime debuted with this behaviour.

最初的 JVM 没有分代垃圾收集器,尽管这个特性是迅速添加的。SunOracle 和其他公司实施的第一代收集器往往是 Mark and Sweep。人们意识到,标记-清除-压缩方法将导致更好的内存局部性,证明额外的复制开销是合理的。CLR 运行时以这种行为首次亮相。

A difference between SunOracle's and Microsoft's GC implementation 'ethos' is one of configurability.

SunOracle 和 Microsoft 的 GC 实现“精神”之间的区别在于可配置性之一。

Sun's provides a vast number of options (at the command line) to tweaks aspects of the GC or switch it between different modes. Many options are of the -X or -XX to indicate their lack of support across different versions or vendors. The CLR by contrast provides next to no configurability; your only real option is the use of the server or client collectors which optimise for throughput verses latency respectively.

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

Active research in GC strategies is ongoing in both companies (and in open source implementations) current approaches being used in the most recent GC implementations are per thread eden areas (improving locality and allowing the eden collection to potentially not cause a full pause) as well as pre-tenuring approaches, which try to avoid placing certain allocations into the eden generation.

两家公司(以及开源实现)都在积极研究 GC 策略最近的 GC 实现中使用的当前方法是每个线程 eden 区域(改善局部性并允许 eden 收集可能不会导致完全暂停)以及作为 pre-tenuring 方法,它试图避免将某些分配放入 eden 代。

回答by duffymo

Java 5 introduced a lot of changes into its GC algorithms.

Java 5 对其 GC 算法进行了大量更改。

I'm not a C# maven, but these two articles suggest to me that both have evolved away from simple mark and sweep and towards newer generation models:

我不是 C# 专家,但这两篇文章告诉我,两者都已经从简单的标记和扫描演变为新一代模型:

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.htmlhttp://www.csharphelp.com/archives2/archive297.html

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html http://www.csharphelp.com/archives2/archive297.html

回答by Brian Rasmussen

This is just to add to ShuggyCoUk's excellent answer. The .NET GC also uses what is know as the large object heap (LOH). The CLR preallocates a bunch of objects on the LOH and all user allocated objects of at least 85000 bytes are allocated on the LOH as well. Furthermore, double[]of 1000 elements or more are allocated on the LOH as well due to some internal optimization.

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

The LOH is handled differently than the generational heaps in various ways:

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

  • It is only cleaned during a full collect and it is never compacted like the generational heaps.
  • Allocation from the LOH is done via a free list much like mallocis handled in the C runtime, whereas allocations from the generational heap is essentially done by just moving a pointer in generation 0.
  • 它仅在完整收集期间被清理,并且永远不会像代堆那样被压缩。
  • LOH 中的分配是通过一个空闲列表完成的,就像malloc在 C 运行时中处理的那样,而分代堆中的分配基本上是通过移动第 0 代中的指针来完成的。

I don't know if the JVM has something similar, but it is essential information on how memory is handled in .NET so hopefully, you find it useful.

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

回答by Jason Baker

If I recall correctly, the JVM doesn't release deallocated memory back to the operating system as the CLR does.

如果我没记错的话,JVM 不会像 CLR 那样将释放的内存释放回操作系统。