相同點: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