前言
說來真是好笑巡扇,我只是想了解值類型和引用類型,結(jié)果跳出來一大堆我本不該承受的東西。
線程
每個正在運(yùn)行的程序都對應(yīng)著一個進(jìn)程(process)
一睁,在一個進(jìn)程內(nèi)部可以有一個或多個線程(thread)
。
堆棧和堆
每個線程都擁有一塊“自留地”佃却,稱為“線程堆棧”者吁,大小為1M用于保存自身數(shù)據(jù)。
這里分為兩個概念饲帅,根據(jù) 數(shù)據(jù)類型 的不同分為 堆棧 和 堆复凳,這里的堆在.NET中叫 托管堆,其實(shí)是同一個東西灶泵,因?yàn)槭褂没?NET CLR的編譯器開發(fā)的代碼叫托管代碼育八,所以...
內(nèi)存分配類型
兩種:
- 堆棧內(nèi)存
堆棧負(fù)責(zé)保持跟蹤應(yīng)用程序運(yùn)行需要的內(nèi)存
- 堆內(nèi)存
對象的堆積,用于動態(tài)內(nèi)存分配
public void Method1()
{
// Line 1
int i=4;
// Line 2
int y=2;
//Line 3
class1 cls1 = new class1();
}
步驟:
- 執(zhí)行第一行赦邻,編譯器分配一小塊叫堆棧的內(nèi)存髓棋。
- 執(zhí)行第二行,編譯器分配的內(nèi)存堆疊在第一塊內(nèi)存的頂部惶洲。
指針總是指在最后一塊內(nèi)存的后面一個位置
注:內(nèi)存分配和釋放使用的是LIFO(Last in first out按声,后進(jìn)先出)
邏輯。 - 執(zhí)行第三行恬吕,創(chuàng)建對象時签则,它在堆棧上創(chuàng)建一個指針
可以理解為路徑
,真實(shí)對象的內(nèi)容儲存在叫堆的內(nèi)存中币呵。
4.當(dāng)退出這個方法時怀愧,分配到堆棧上的所有內(nèi)存變量被清除,所有與int數(shù)據(jù)類型關(guān)聯(lián)的變量以LIFO方式從堆棧中接觸分配余赢。
關(guān)系如圖:
垃圾回收器
既然提到堆的話必須說一下這個垃圾回收器GC
芯义,因?yàn)槎褍?nèi)存的分配需要通過Garbage Collector(垃圾回收器:GC)解除分配。
垃圾回收器在后臺做什么呢妻柒?
為了知道內(nèi)存的分配的扛拨,GC以根對象全局:應(yīng)用程序(包括:靜態(tài)或處于活動中的局部變量以及寄存器指向的對象)
為根目錄找到下級的內(nèi)存分配地址,并記錄下來“繪制”對象列表根對象直接或間接引用的對象列表举塔,其他沒在列表的將被釋放
绑警,如果內(nèi)存分配有更新求泰,對象列表也會更新。
生存期垃圾回收
垃圾回收器將內(nèi)存分為多個托管堆计盒,每個代表一種生存期等級GC支持三個等級(0級渴频、1級、2級)
北启。
值得一提的是卜朗,這個等級劃分存在一個規(guī)則:
- 如果一個對象是新創(chuàng)建的,那么它的生命期可能很短咕村。
- 如果一個對象是原來存在的场钉,它可能會有更長的生命。
流程:當(dāng)應(yīng)用程序創(chuàng)建對象時懈涛,這些對象首先被放在0級對象列表中逛万,當(dāng)0級列表滿了,GC開始釋放內(nèi)存資源如上所說把應(yīng)用程序不引用的對象刪除
批钠。如果不能在0級刪除宇植,那么該對象被提升等級,依次類推.Net運(yùn)行時支持的最大級是2級
...
那么未處理的對象越多埋心,托管堆的大小隨之增大当纱,因此可能存在性能問題。
終結(jié)器-Finalize()
為什么對象會等級提升踩窖,我們來看看處理器的步驟:
- 新對象創(chuàng)建,對象被放入0級托管堆晨横。
- 當(dāng)0級列表填滿時洋腮,GC運(yùn)行并清理內(nèi)存。
- 如果對象沒有析構(gòu)函數(shù)
C#編譯器會把析構(gòu)函數(shù)翻譯(重命名)為終結(jié)器finalize()
并且不被引用手形,那么GC把它們清除啥供;如果有,GC把它們放入終結(jié)隊列中之后移到Freachable隊列等級提升
中并在下一次迭代中執(zhí)行每個對象的Finalize方法库糠。 - 當(dāng)Finalize方法執(zhí)行之后被標(biāo)識可回收釋放掉伙狐。
那么在調(diào)用Finalize方法時,對象執(zhí)行方法使對象可達(dá)瞬欧,那么該對象將復(fù)活贷屎。
簡單的說有析構(gòu)函數(shù)的對象會在內(nèi)存中存活的時間更長
.Net提供IDisposable接口
class clsMyClass : IDisposable
{
public clsMyClass()
{
}
~clsMyClass()
{
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
這里“SuppressFinalize”指示GC不要調(diào)用Finalize方法,所以不會發(fā)生GC的二次調(diào)用艘虎。
引文
- .NET中六個你必須知道的重要概念之堆棧(stack)和堆(heap)
- 深入理解.NET內(nèi)存回收機(jī)制
- .net最佳實(shí)踐二:使用finalize/dispose模式提升垃圾回收器性能
- 【譯】.Net 垃圾回收機(jī)制原理(一)
END
- 如果文章內(nèi)容能誤導(dǎo)大家那真是再好不過了唉侄,嘻嘻嘻。
- 文章內(nèi)容可能持續(xù)變更野建,修改或添加更多內(nèi)容属划,以確保內(nèi)容的準(zhǔn)確性恬叹。
- 文章中大部分觀點(diǎn)來自引文的總結(jié),寫文章的初衷是為了方便回憶同眯。
- 更新時間:2018-09-11