Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .Net与Java垃圾收集器_C#_Java_Garbage Collection - Fatal编程技术网

C# .Net与Java垃圾收集器

C# .Net与Java垃圾收集器,c#,java,garbage-collection,C#,Java,Garbage Collection,有人知道Java和.Net垃圾收集器之间的主要区别吗?网络搜索没有透露太多信息,这是一个测试中出现的问题。我发现: 在J2SE平台1.4.2版中,有四个垃圾收集器可供选择,但用户没有明确的选择,总是选择串行垃圾收集器。在版本5.0中,收集器的选择基于启动应用程序的机器的类别 还有这个 正如JVM管理对象的销毁一样,CLR也通过标记和压缩垃圾收集算法管理对象的销毁 我希望这会有所帮助……区别在于CLR(.Net)GC和JVM GC之间,而不是语言本身。 两者都会发生变化,其行为规范也会松动,以允

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

我发现:

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

还有这个

正如JVM管理对象的销毁一样,CLR也通过标记和压缩垃圾收集算法管理对象的销毁


我希望这会有所帮助……

区别在于CLR(.Net)GC和JVM GC之间,而不是语言本身。 两者都会发生变化,其行为规范也会松动,以允许在不影响程序正确性的情况下进行更改

存在一些历史差异,主要是由于.Net的设计借鉴了java(和其他基于gc的平台)的发展经验。在下文中,不要假设.Net one在某种程度上是优越的,因为它从一开始就包含了功能,它只是后来出现的结果

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

最初的JVM没有分代的垃圾收集器,尽管这个特性很快被添加了。 SunOracle和其他公司实现的第一代收集器倾向于标记和扫描。人们意识到,标记扫描压缩方法将导致更好的内存局部性,从而证明额外的复制开销是合理的。CLR运行时首次使用此行为

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

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


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

Java5对其GC算法进行了大量更改

我不是一个C#maven,但这两篇文章向我表明,两者都已从简单的标记和扫描模式演变为新一代模式:


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

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

  • 它只在一次完整的收集过程中才被清理,而且从未像世代堆积一样被压实
  • LOH的分配是通过一个自由列表完成的,就像C运行时处理的
    malloc
    一样,而代际堆的分配基本上是通过在第0代中移动指针来完成的

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

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

回答得很好。仅仅是事实-很好地避免了宗教战争,-1是否愿意添加一个原因?值得注意的是,“正常”。net使用一种称为“写围栏”的技术来跟踪自上次升级以来已写入的对象。据我所知,如果一个对象从gen0升级到gen1,并且从那以后就没有写过,那么它不可能包含对gen0对象的任何引用;在gen0集合期间,不需要检查其中包含的任何引用,因为它引用的唯一对象将被假定为“活动的”。在gen0收集过程中跳过非编写的gen1/gen2对象是一个巨大的成功。@supercat我希望大多数(所有?)java代GC使用相同的技术老实说,我看不到java有任何阻止使用它的功能。@ShuggyCoUk:我相信有些人会,但如果有些人不这样做,也不会感到惊讶,因为写围栏不是免费的,而且由于世代GC可以提供一些好处,成本非常低,没有它们。如果我正在设计一个框架,我将提供一种方法来指定某些类是不可变的(包括不可变的数组类型);即使是不支持写防护的实现也可以从知道gen1不可变对象不会包含任何对任何gen0对象的引用中获益。好的一点是,通过编辑将其他对象的扩展集成到您自己的答案中被认为是一种好的形式吗,如果是这样的话,你应该通过内联还是通过评论来获得信用?现在它有一个选项来压缩LOH,这是默认的。这是一个更显著的区别。