国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

.NET的堆和棧01,基本概念、值類型內存分配

2019-11-17 03:02:43
字體:
來源:轉載
供稿:網友

.NET的堆和棧01,基本概念、值類型內存分配

當我們對.NET Framework的一些基本面了解之后,實際上,還是很有必要了解一些更底層的知識。比如.NET Framework是如何進行內存管理的,是如何垃圾回收的......這樣,我們才能寫出更高性能的程序。

在.NET Framework中,有2個地方幫我們保存管理數據:一個是"堆",也叫"托管堆",由.NET Framework的垃圾收集器(Garbage Collection, GC)管理;另一個是"棧",也叫"線程堆棧",由操作系統直接管理。它們都寄宿在操作系統內存。

本篇主要包括:■ 什么是"棧"■ 什么是"堆"■ 值類型內存分配 ※ 在方法內的值類型內存分配 ※ 在引用類型內部的值類型內存分配■ 練習題

什么是"棧"

可以把"棧"想像成由下而上堆疊起來的盒子,值類型實例存儲于此。1

在應用程序中,每當調用一個方法,就相當于在"堆"上放上了一個盒子A,這時,應用程序只能使用處在"棧"最上方、剛被放上的這個盒子A,當方法執行結束,相當于把最上方的盒子A扔掉。接下來,剛才還在A下面的盒子B就處在"棧"的最上方了,于是應用程序又開始使用盒子B,以此類推。而且,每當把最上面的盒子扔掉,其對應的內存也被自動釋放。

棧的優點是執行效率高,缺點是存儲容量有限。

在.NET Framework中,所有派生于System.ValueType的就是值類型,值類型實例位于"棧"。值類型包括:● bool● byte● char● decimal● double● enum● float● int● long● sbyte● short● stuct● uint● ulong● short

什么是"堆"

可以把"堆"想像成一些擺放無序的盒子,引用類型實例存儲于此。2

我們可以在任何時候,使用任何盒子。我們需要借助垃圾收集器(Garbage Collection, GC)的自動回收機制或手動處理,以保證"堆"的盒子被及時回收。

另外,根據引用類型實例的大小,"堆"分為"GC堆"和"LOH(Large Object Heap)堆",當引用類型實例大小小于85000個字節的時候,實例被分配在"GC堆"上;當實例大小大于或等于于85000個字節的時候,實例被分配在"LOH(Large Object Heap)堆"。

在.NET Framework中,所有派生于System.Object的就是引用類型,引用類型實例位于"堆"。引用類型包括:● 類 class● 接口 interface● 委托 delegate● object● string

值類型內存分配

在方法內的值類型內存分配

public int Add(int x){    int result;    result = x + 2;    return result;}

1、在執行Add(int x)方法之前,方法參數x被存放到"棧"的頂部。3

2、在"method table"中搜尋Add()方法,如果找不到,就讓JIT及時編譯再存放到"method table"中去。

3、開始執行Add(int x)方法,局部變量result也需要"棧"中的一些內存。4

4、當方法執行完畢,先釋放result,再釋放x,線程堆棧指針重新指向。5

在引用類型內部的值類型內存分配

public class MyClass{    public int MyValue;}public MyClass Add(int x){    MyClass result = new MyClass();    result.MyValue = x + 2;    return result;}

1、在執行Add(int x)方法之前,方法參數x被存放到"棧"的頂部。3

2、在"method table"中搜尋Add()方法,如果找不到,就讓JIT及時編譯再存放到"method table"中去。

3、開始執行Add(int x)方法,執行MyClass result = new MyClass()先在托管堆上創建一個MyClass的實例,然后在棧上開辟一塊空間并指向實例地址。6

4、當方法執行完畢,在棧中由上到下依次釋放內存。7

此時,在托管堆上的MyClass實例如何處理呢?

5、此時,垃圾回收器登場了,他在托管堆中搜尋那些不再被引用的對象實例,然后實施回收。

練習題

public int ReturnValue()          {                int x = new int();                x = 3;                int y = new int();                y = x;                      y = 4;                          return x;          }

結果是:3, 因為值類型x變量,在方法執行結束之前,一直存在于棧上。

public int ReturnValue2()          {                MyInt x = new MyInt();                x.MyValue = 3;                MyInt y = new MyInt();                y = x;                                 y.MyValue = 4;                              return x.MyValue;          }
結果是:4,因為,當通過y=x把x賦值給y時,實際上是把x在托管堆上的地址賦值y,也就是,棧上的x和y都指向托管堆上的同一個對象實例,改變y的字段值,相當于改變x的字段值。

參考資料:C# Heap(ing) Vs Stack(ing) in .NET: Part I《你必須知道的.NET(第2版)》,作者王濤。

".NET的堆和棧"系列包括:

.NET的堆和棧01,基本概念、值類型內存分配

.NET的堆和棧02,值類型和引用類型參數傳遞以及內存分配

.NET的堆和棧03,引用類型對象拷貝以及內存分配

.NET的堆和棧04,對托管和非托管資源的垃圾回收以及內存分配


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 屏东市| 深水埗区| 玉龙| 宿迁市| 贵州省| 和龙市| 安新县| 哈密市| 平邑县| 河北省| 高青县| 水富县| 安岳县| 称多县| 昌吉市| 西昌市| 柳州市| 会昌县| 灵丘县| 崇左市| 蒙城县| 科技| 梅州市| 青田县| 兴隆县| 无为县| 镇雄县| 温宿县| 汉中市| 枣庄市| 田林县| 金沙县| 绥江县| 兴业县| 驻马店市| 习水县| 黄骅市| 永安市| 德庆县| 边坝县| 蒲江县|