ASP.NET堆和棧一之基本概念和值類型內(nèi)存分配
".NET的堆和棧"系列:
ASP.NET堆和棧二之值類型和引用類型參數(shù)傳遞和內(nèi)存分配
ASP.NET堆和棧三之引用類型對(duì)象拷貝和內(nèi)存分配
ASP.NET堆和棧四之對(duì)托管和非托管資源垃圾的回收和內(nèi)存分配
當(dāng)我們對(duì).NET Framework的一些基本面了解之后,實(shí)際上,還是很有必要了解一些更底層的知識(shí)。比如.NET Framework是如何進(jìn)行內(nèi)存管理的,是如何垃圾回收的......這樣,我們才能寫出更高性能的程序。
在.NET Framework中,有2個(gè)地方幫我們保存管理數(shù)據(jù):一個(gè)是"堆",也叫"托管堆",由.NET Framework的垃圾收集器(Garbage Collection, GC)管理;另一個(gè)是"棧",也叫"線程堆棧",由操作系統(tǒng)直接管理。它們都寄宿在操作系統(tǒng)內(nèi)存。
什么是"棧"
可以把"棧"想像成由下而上堆疊起來的盒子,值類型實(shí)例存儲(chǔ)于此。
在應(yīng)用程序中,每當(dāng)調(diào)用一個(gè)方法,就相當(dāng)于在"堆"上放上了一個(gè)盒子A,這時(shí),應(yīng)用程序只能使用處在"棧"最上方、剛被放上的這個(gè)盒子A,當(dāng)方法執(zhí)行結(jié)束,相當(dāng)于把最上方的盒子A扔掉。接下來,剛才還在A下面的盒子B就處在"棧"的最上方了,于是應(yīng)用程序又開始使用盒子B,以此類推。而且,每當(dāng)把最上面的盒子扔掉,其對(duì)應(yīng)的內(nèi)存也被自動(dòng)釋放。
棧的優(yōu)點(diǎn)是執(zhí)行效率高,缺點(diǎn)是存儲(chǔ)容量有限。
在.NET Framework中,所有派生于System.ValueType的就是值類型,值類型實(shí)例位于"棧"。值類型包括:
- bool
- byte
- char
- decimal
- double
- enum
- float
- int
- long
- sbyte
- short
- stuct
- uint
- ulong
- short
什么是"堆"
可以把"堆"想像成一些擺放無序的盒子,引用類型實(shí)例存儲(chǔ)于此。
我們可以在任何時(shí)候,使用任何盒子。我們需要借助垃圾收集器(Garbage Collection, GC)的自動(dòng)回收機(jī)制或手動(dòng)處理,以保證"堆"的盒子被及時(shí)回收。
另外,根據(jù)引用類型實(shí)例的大小,"堆"分為"GC堆"和"LOH(Large Object Heap)堆",當(dāng)引用類型實(shí)例大小小于85000個(gè)字節(jié)的時(shí)候,實(shí)例被分配在"GC堆"上;當(dāng)實(shí)例大小大于或等于于85000個(gè)字節(jié)的時(shí)候,實(shí)例被分配在"LOH(Large Object Heap)堆"。
在.NET Framework中,所有派生于System.Object的就是引用類型,引用類型實(shí)例位于"堆"。引用類型包括:
- 類 class
- 接口 interface
- 委托 delegate
- object
- string
值類型內(nèi)存分配
在方法內(nèi)的值類型內(nèi)存分配
public int Add(int x) { int result; result = x + 2; return result; }
1、在執(zhí)行Add(int x)方法之前,方法參數(shù)x被存放到"棧"的頂部。
2、在"method table"中搜尋Add()方法,如果找不到,就讓JIT及時(shí)編譯再存放到"method table"中去。
3、開始執(zhí)行Add(int x)方法,局部變量result也需要"棧"中的一些內(nèi)存。
4、當(dāng)方法執(zhí)行完畢,先釋放result,再釋放x,線程堆棧指針重新指向。
在引用類型內(nèi)部的值類型內(nèi)存分配
public class MyClass { public int MyValue; } public MyClass Add(int x) { MyClass result = new MyClass(); result.MyValue = x + 2; return result; }
1、在執(zhí)行Add(int x)方法之前,方法參數(shù)x被存放到"棧"的頂部。
2、在"method table"中搜尋Add()方法,如果找不到,就讓JIT及時(shí)編譯再存放到"method table"中去。
3、開始執(zhí)行Add(int x)方法,執(zhí)行MyClass result = new MyClass()
先在托管堆上創(chuàng)建一個(gè)MyClass的實(shí)例,然后在棧上開辟一塊空間并指向?qū)嵗刂贰?/p>
4、當(dāng)方法執(zhí)行完畢,在棧中由上到下依次釋放內(nèi)存。
此時(shí),在托管堆上的MyClass實(shí)例如何處理呢?
5、此時(shí),垃圾回收器登場了,他在托管堆中搜尋那些不再被引用的對(duì)象實(shí)例,然后實(shí)施回收。
練習(xí)題
public int ReturnValue() { int x = new int(); x = 3; int y = new int(); y = x; y = 4; return x; }
結(jié)果是:3, 因?yàn)橹殿愋蛒變量,在方法執(zhí)行結(jié)束之前,一直存在于棧上。
public int ReturnValue2() { MyInt x = new MyInt(); x.MyValue = 3; MyInt y = new MyInt(); y = x; y.MyValue = 4; return x.MyValue; }
結(jié)果是:4,因?yàn)?,?dāng)通過y=x把x賦值給y時(shí),實(shí)際上是把x在托管堆上的地址賦值y,也就是,棧上的x和y都指向托管堆上的同一個(gè)對(duì)象實(shí)例,改變y的字段值,相當(dāng)于改變x的字段值。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
asp.net 將設(shè)有過期策略的項(xiàng)添加到緩存中
調(diào)用 Insert 方法,將絕對(duì)過期時(shí)間或彈性過期時(shí)間傳遞給該方法。2009-04-04asp.net中對(duì)象失去焦點(diǎn)時(shí)自動(dòng)提交數(shù)據(jù) V2
一年多前,Insus.NET有寫過一篇 《對(duì)象失去焦點(diǎn)時(shí)自己動(dòng)提交數(shù)據(jù)》,那一篇是依賴Linkbutton來做隱藏提交。是否有不用依賴Linkbutton方法呢? 答案是肯定的2012-11-11asp.net實(shí)現(xiàn)DataList與Repeater嵌套綁定的方法
這篇文章主要介紹了asp.net實(shí)現(xiàn)DataList與Repeater嵌套綁定的方法,結(jié)合實(shí)例形式分析了DataList與Repeater的步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-04-04asp.net ajax實(shí)現(xiàn)無刷新驗(yàn)證碼
實(shí)現(xiàn)ajax無刷新驗(yàn)證碼首先需要兩個(gè)aspx頁面,第一個(gè)用來展示,另一個(gè)用來后臺(tái)刷新驗(yàn)證碼2011-10-10ASP.NET?Core?6.0?基于模型驗(yàn)證的數(shù)據(jù)驗(yàn)證功能
這篇文章主要介紹了ASP.NET?Core?6.0?基于模型驗(yàn)證的數(shù)據(jù)驗(yàn)證,本文描述的數(shù)據(jù)驗(yàn)證方案,是基于官方的模型驗(yàn)證(Model validation),需要的朋友可以參考下2022-07-07ASP.NET+Web服務(wù)實(shí)現(xiàn)軟件共享
ASP.NET+Web服務(wù)實(shí)現(xiàn)軟件共享...2006-09-09.net通過Action進(jìn)行Options參數(shù)的傳遞的方法
在.NET Core中,使用Action和Options參數(shù)方式配置服務(wù)并將配置信息對(duì)象注冊(cè)到IServiceCollection的好處在于,它提供了更高級(jí)別的可配置性和可擴(kuò)展性,這篇文章主要介紹了.net通過Action進(jìn)行Options參數(shù)的傳遞,你知道是怎么實(shí)現(xiàn)的嗎,需要的朋友可以參考下2023-12-12ASP.NET中利用存儲(chǔ)過程實(shí)現(xiàn)模糊查詢
ASP.NET中利用存儲(chǔ)過程實(shí)現(xiàn)模糊查詢...2006-09-09