Java和.NET中的垃圾回收機制比較

相同點:

都採用了分代的機制。

都支持併發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字節的)需要分配空間時,就可以放在這裏。

這塊地方和分代機制的不同之處在於,這個地方只有當發生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.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

http://www.mincoder.com/article/4284.shtml

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章