手机版
你好,游客 登录 注册
背景:
阅读新闻

Java和.NET中的垃圾回收机制比较

[日期:2017-02-02] 来源:Linux社区  作者:cnn237111 [字体: ]

Java和.NET中的垃圾回收机制相同点:

都采用了分代的机制。

都支持并发GC。

都没有采用引用计数方式,而是采用了追踪技术。

.NET中,可以通过代码GC.Collect() 强制要求CLR进行垃圾回收(由于垃圾回收是异步的,CLR有一个专用的线程负责垃圾回收,因此,即使调用GC.Collect,也并不是实时的调用了Finalize,因此要保证确实调用了析构方法,可以使用语句GC.WaitForPendingFinalizers()来确保析构方法真的被运行了,参考http://www.linuxidc.com/Linux/2017-02/140121.htm

Java中也可以通过System.gc() 强制要求进行垃圾回收。(事实上也仅仅是建议JVM执行垃圾回收,JVM并不一定立即做回收行为。)

不同点:

CLR预留了一块大空间,称作large object heap (LOH),目的是当有大对象(超过85000字节的)需要分配空间时,就可以放在这里。

这块地方和分代机制的不同之处在于,这个地方只有当发生full GC的时候,才会回收,而且这块地方不会被压缩。

Java中可以通过配置参数,使得大对象(大于设定的阈值)直接进入老年代(避免在年轻代上做大量的复制操作)。

JVM回收的内存的,仅仅在某些条件下才返回给操作系统。(详见:http://stackoverflow.com/questions/366658/java-6-excessive-memory-usage#367933

.NET回收的内存,直接给返还给操作系统。

JVM在的垃圾回收机制,提供了大量的可配置参数。

而CLR的垃圾回收机制几乎没什么可以配置的(仅有的配置似乎就是工作站模式(Workstation)和服务器模式(Server))。

都支持并发GC。JAVA是在老年代上支持并发GC,采用的CMS收集器。

.NET的并发GC只在第2代上,并且在工作站模式下才会有。

Java分成年轻代,老年代,永久代。

.NET分第0代,第1代,第2代。

.NET中采用了标记,压缩的方式。

JAVA由于收集器很多,因此不限于一种算法。

 

年轻代

老年代

方式

Serial收集器

复制算法

             

单线程,stop the world

SerialOld收集器                  

             

标记整理算法

单线程,stop the world                  

ParNew收集器

复制算法

标记整理算法

多线程,stop the world

Parallel Scavenge收集器

复制算法                
           
多线程,stop the world               

CMS收集器

             

标记清除

单线程

G1收集器

复制

标记整理

             

Java垃圾回收的几篇文章
http://www.linuxidc.com/Linux/2017-02/140122.htm
http://www.linuxidc.com/Linux/2017-02/140123.htm

.NET垃圾回收的几篇文章
https://msdn.microsoft.com/zh-cn/library/ee787088(v=vs.110).aspx
http://www.mincoder.com/article/4284.shtml

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-02/140124.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款