首先堆棧和堆(託管堆)都在進程的虛擬內存中。(在32位處理器上每一個進程的虛擬內存爲4GB)堆棧stack 堆棧中存儲值類型。堆棧其實是向下填充,即由高內存地址指向地內存地址填充。堆棧的工做方式是先分配內存的變量後釋放(先進後出原則)。堆棧中的變量是從下向上釋放,這樣就保證了堆棧中先進後出的規則不與變量的生命週期起衝突!堆棧的性能很是高,可是對於全部的變量來講還不太靈活,並且變量的生命週期必須嵌套。一般咱們但願使用一種方法分配內存來存儲數據,而且方法退出後很長一段時間內數據仍然可使用。此時就要用到堆(託管堆)!堆(託管堆)heap堆(託管堆)存儲引用類型。此堆非彼堆,.NET中的堆由垃圾收集器自動管理。與堆棧不一樣,堆是從下往上分配,因此自由的空間都在已用空間的上面。好比建立一個對象:Customer cus;cus = new Customer();申明一個Customer的引用cus,在堆棧上給這個引用分配存儲空間。這僅僅只是一個引用,不是實際的Customer對象!cus佔4個字節的空間,包含了存儲Customer的引用地址。接着分配堆上的內存以存儲Customer對象的實例,假定Customer對象的實例是32字節,爲了在堆上找到一個存儲Customer對象的存儲位置。.NET運行庫在堆中搜索第一個從未使用的,32字節的連續塊存儲Customer對象的實例!而後把分配給Customer對象實例的地址賦給cus變量!從這個例子中能夠看出,創建對象引用的過程比創建值變量的過程複雜,且不能避免性能的下降!實際上就是.NET運行庫保存對的狀態信息,在堆中添加新數據時,堆棧中的引用變量也要更新。性能上損失不少!有種機制在分配變量內存的時候,不會受到堆棧的限制:把一個引用變量的值賦給一個相同類型的變量,那麼這兩個變量就引用同一個堆中的對象。當一個應用變量出做用域時,它會從堆棧中刪除。但引用對象的數據仍然保留在堆中,一直到程序結束 或者 該數據不被任何變量應用時,垃圾收集器會刪除它