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收集器
復制算法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