程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> C#棧和堆的區別淺談

C#棧和堆的區別淺談

編輯:C#基礎知識

理解堆與棧對於理解.NET中的內存管理、垃圾回收、錯誤和異常、調試與日志有很大的幫助。垃圾回收的機制使程序員從復雜的內存管理中解脫出來,雖然絕大多數的C#程序並不需要程序員手動管理內存,但這並不代表程序員就無需了解分配的對象是如何被回收的,在一些特殊的場合仍需要程序員手動進行內存管理。

在32位的處理器上,每個進程的虛擬內存為4GB,.NET會在這4GB的內存塊中開辟出3塊內存,分別作為棧、托管堆、和非托管堆

堆(heap):

堆是從下往上分配,所以已用的空間在自由空間下面,C#中所有引用類型的對象分配在托管堆上,托管堆在內存上是連續分配的,並且內存對象的釋放受垃圾收集機制的管理,效率相對於棧來說要低的多。

棧(stack):

棧是自上向下進行填充,即由高內存地址指向低內存地址,並且內存分配是連續的,C#中所有的值類型和引用類型的引用都分配在棧上,棧根據後進先出的原則,依次對分配和釋放內存對象。

對象內存的分配與銷毀:

當一個類的實例對象創建的時候,這個對象的不同成員按類別被分配到了不同的內存區域,值類型和引用類型的指針被分配到了棧上,引用類型的實例對象被分配到了托管堆上,靜態成員被分配到了全局數據區。此時棧上的指針會指向堆上的對象。當對象使用完以後,引用和實際對象的聯系就會斷開,從而從而使對象冬眠。因為棧具有自我維護性,它的內存管理可以通過操作系統來完成,而此時堆上的冬眠對象就需要通過垃圾回收器(GC)使用一定的算法來進行回收,釋放對象所占據的內存。

C#中的深拷貝與淺拷貝

深拷貝:又稱深度克隆,它完全是新對象的產生,不僅復制所有的非靜態值類型成員,而且復制所有引用類型成員的實際對象。(即棧上和堆上的成員均進行復制)

淺拷貝:又稱影子克隆,只復制原始對象中的所有的非靜態的值類型成員和所有引用類型成員的引用,就是說,原始對象和新對象共享所有引用類型成員的對象實例。(即只復制棧上的成員)

注:不管是深拷貝還是淺拷貝,都不會復制全局數據區的成員,因為全局數據區的成員是靜態成員,它屬於某一個類,並不屬於類的實例對象,因此無法復制。

C#中的深拷貝可以通過實現ICloneable接口來實現,但是在不是必須實現ICloneable接口的情況下,應避免類型繼承ICloneable接口。因為這樣做將強制所有的子類必須實現ICloneable接口,否則子類的新成員將不能被類型的深拷貝所覆蓋。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved