相同点:html
都采用了分代的机制。java
都支持并发GC。算法
都没有采用引用计数方式,而是采用了追踪技术。服务器
.NET中,能够经过代码GC.Collect() 强制要求CLR进行垃圾回收(因为垃圾回收是异步的,CLR有一个专用的线程负责垃圾回收,所以,即便调用GC.Collect,也并非实时的调用了Finalize,所以要保证确实调用了析构方法,可使用语句GC.WaitForPendingFinalizers()来确保析构方法真的被运行了,参考http://cnn237111.blog.51cto.com/2359144/1343004)
多线程
Java中也能够经过System.gc() 强制要求进行垃圾回收。(事实上也仅仅是建议JVM执行垃圾回收,JVM并不必定当即作回收行为。)
并发
不一样点:异步
CLR预留了一块大空间,称做large object heap (LOH),目的是当有大对象(超过85000字节的)须要分配空间时,就能够放在这里。ide
这块地方和分代机制的不一样之处在于,这个地方只有当发生full GC的时候,才会回收,并且这块地方不会被压缩。spa
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.cnblogs.com/shudonghe/p/3457990.html
http://blog.csdn.net/zhangerqing/article/details/8214365
.NET垃圾回收的几篇文章
https://msdn.microsoft.com/zh-cn/library/ee787088(v=vs.110).aspx