面試題之C# 記憶體管理與垃圾回收 你說說C# 的記憶體管理是怎麼樣的 這句話我記了一個多禮拜了, 自從上次東北師大面試之後, 具體請看<隨便扯扯東北師大的面試>. 國慶閑著沒事, 就大概瞭解了一下, 其實大二學習C# 的時候接觸過, 只不過那會看的也看的懵懂, 我看的是vir in C#, 順便查了些 ...
面試題之C# 記憶體管理與垃圾回收
你說說C# 的記憶體管理是怎麼樣的
這句話我記了一個多禮拜了, 自從上次東北師大面試之後, 具體請看<隨便扯扯東北師大的面試>. 國慶閑著沒事, 就大概瞭解了一下, 其實大二學習C# 的時候接觸過, 只不過那會看的也看的懵懂, 我看的是vir in C#, 順便查了些資料, 講真, 看的頭痛。現在過了這麼久了, 學了這麼久了, 再回來看看其實也不難, 當然深入去瞭解就gg了, 我還記得我的回答是:C# 有個GC可以自己回收, 在加上引用計數。沒錯, 我回答的就是這麼籠統, 現在想想還是緊張了, 自己之前接觸過, 其實都有印象, 下次面試不要急, 慢慢回想。
.NET 中的資源分為兩類: 托管資源和非托管資源, 既然有兩類資源, 那麼理所當然就有兩種回收方式。托管資源由CLR管理的存在於托管堆上的稱為托管資源, 它是由CLR管理, 存在於托管堆上, CLR會在合適的時候調用GC進行回收。非托管資源:
比如資料庫連接, 文件句柄, socket等不由CLR管理的資源, GC只回收托管資源, 不回收非托管資源。那麼什麼時候GC會回收記憶體?當一個對象的引用計數為0的時候, CLR調用GC回收記憶體。而相對於非托管資源來講, 由於不受CLR的管理, 因此我們需要手動回收記憶體, 調用Dispose方法是個不錯的選擇, 但是你需要繼承自IDisposable介面的類, 看看這個介面的實現:
[ComVisible(true), __DynamicallyInvokable] public interface IDisposable { // Methods [__DynamicallyInvokable] void Dispose(); }
還有個Finalize 我沒有去瞭解, 大概看了下, 等會我會給出鏈接, 你可以自己看看。我們在寫資料庫連接語句的時候, 經常會使用的一種寫法:
using(SqlConnection = new SqlConnection(...)) { ////ADO.NET語句 }
這是比較標準的寫法, 大三的時候學ado.net, 記得查資料說, 這可以保證資料庫資源的正確釋放, 當時沒有多想, 今天查資料說, using(){}其實就是調用dispose銷毀對象, 而且只有繼承了idispose介面的類型才能銷毀對象, 而且是try...catch...finally的簡化。既然如此, 我們來看看SqlConnection類是不是實現了此介面:
[DefaultEvent("InfoMessage")] public sealed class SqlConnection : DbConnection, ICloneable { // Fields }
看看DbConnection類:
public abstract class DbConnection : Component, IDbConnection, IDisposable { // Fields }
果然, 還真是如此, 就是說一旦出了using語句的控制範圍, 將會自動調用dispose方法銷毀對象資源.據說close方法也是調用了dispose(),看看源碼:
public void Close() { this.Dispose(true); }
好吧, 還真是, 如果我們手動調用ado.net的close, 那也是可以關閉資料庫連接與資料庫資源的。
plus:python的記憶體管理也是通過引用計數來控制的
一點一滴積累, 我還不信我解決不了一個破面試