記憶體分配以及合理使用

2022-02-13 01:44:35 字數 2550 閱讀 3354

1.記憶體分配

a.棧分配

b.對分配

2.合理使用記憶體

.記憶體分配

系統新建乙個執行緒的時候為這個執行緒分配乙個1m(xp系統)大小的空間,棧採用先入後出的原則儲存著資料和指令,當執行完畢後,棧內應該為空,.net **在被編譯成il二進位制後,il就是一系列指令和元資料說明等,這些指令就包含了棧的呼叫,物件的例項化等等,所以棧的空間**是系統完成的。

.net 中物件分配在堆中,並且由gc來**不用的物件所佔的空間。對heap包含gcheap和loaderheap,gcheap表示的是能有gc**的堆區域(堆疊都是邏輯上的),gcheap包含小物件堆和大物件堆(large object heap>=85000位元組).loaderheaper包含high-frequency heap、low-frequecy heap、stub heap。

gcheap 小物件堆與大物件堆最大的不同時gc在**空間的時候,會對小物件堆中的有效物件進行移動,使他們放在一起,對loh不會移動空間。

對小物件堆得**過程是:gc首先認為所有的物件都是可以被**的,然後通過演算法計算哪些物件現在是有效地(在棧上去找存不存在這些空間的引用),把有效地物件給標記出來,然後**不小物件的空間,進而就把這些有效物件移動到一起(這個過程中會計算物件的代數,最多三代,所以是「第三代物件|第二代物件|第一代物件」),在**的時候會優先**第一代物件),同時更新物件在棧中儲存的引用位址為新位址,這樣就有很多的記憶體空間並且是一次分配的(分配的時候有乙個指向最後分配位置的指標,這樣在分配新的物件的時候十分快速,當分配到最後堆空間不夠分配的時候,clr會啟動gc**,所以一般不提倡人為呼叫gc去**記憶體,可能會擾亂clr的正常工作)。

對loh,分配記憶體的時候會挨著隨後乙個分配,如果遇到不能分配的時候,啟動gc ,gc **空間,**後不會移動物件位址(一定空間本身就是乙個不小的消耗),後分配的物件會找乙個能放下自己的空間。這樣降低了記憶體利用。這是乙個綜合的考慮結果(魚與熊掌不可兼得),「85000位元組」也是乙個經驗值。

記憶體條,記憶體條就是乙個電路板,其中有很多的電路元件,晶體是其中的重要組成部分,用過電位(通斷,有無電壓)來表示0或者1,通過乙個匯流排對外表示表示記憶體大小和記憶體位址,定位,通過改變晶體導電性,來達到記錄(寫)的目的。

1..net記憶體管理、垃圾**

2.你必須知道的.net——記憶體分配

3.windows程式設計記憶體篇-實驗講解執行緒棧 

.net 在**中的 物件**和 記憶體利用

1.正確的書寫**

明確finalize,dispose,close。

**中經常會開到對非託管物件的引用比如:com元件,檔案讀寫,資料庫訪問等等。

gc**物件的時候,如果該物件含有對非託管物件的引用,那麼就回提示異常,gc不能結束掉對非託管物件的引用,需要我們手動來實現,為了保證gc**物件的時候能結束掉對非託管引用物件,所以又了finalize方法(析構函式編譯後就編譯成的finalize方法)。finalize,**中不能顯示重寫finalize方法(override方式),通過析構函式結束對非託管物件的引用

因為gc會在一些情況下啟動並**物件,**物件的的時間又可能不是我們想要的(比如:資料訪問,假如我們也寫了finalize方法,但是gc執行延遲,當我們第二次呼叫資料庫連線物件的時候,gc還沒有對該物件**,並且長久的連線也消耗了資源),這時候我們需要另外一種方法,那就是idisposable介面,這個介面.net 類庫中有定義,實現其中的dispose方法,提供顯示地結束掉對非託管**的引用(不同的非託管資源結束引用方式可能不同,比如檔案讀取呼叫closehandle方法(系統方法))。為了更好的的書寫**c#中有using關鍵字,物件使用完後自動呼叫物件的dispose方法,方便我們書寫。

對於檔案讀寫和資料連線這樣珍貴的非託管資源(具有獨占性),我們一般是在想用的時候主動的開啟引用,不用的時候就結束掉,有乙個成對的「開-關」關係,所以習慣山我們會有乙個open和close方法。

所以,我們在寫關於非託管的引用的時候,就最好把finalize,dispose,close方法都合理的運用上。

2.合理使用大物件

大物件占用不少空間,有不利於gc的**,怎麼辦呢?

其一:使用小物件,把物件轉換成小物件(比如:把大字串使用過個小字串來儲存);

其二:對物件弱引用:(weakreference類):這個類的原理,比如 weakreference wr = new weakreference(a); a是乙個大物件,占用不少空間,當使用弱引用後,當gc**空間的時候即使在我們程式中沒又被標記無效(a= null),a還是會被**,從而節約了空間。後期再想使用怎麼辦了?先判斷一下wr.target是否為null,如果為null則表示被**掉了,需要重新建立分配a,如果不為null,則表示還沒有被gc**掉,可以繼續使用。這也是乙個妥協的做法。

net陷阱之五:奇怪的outofmemoryexception——大物件堆引起的問題與對策  

system.outofmemoryexception: 

weakreference 類

記憶體管理以及分配

前面有型別的 叫定義 前面無型別的 叫使用 alloc 開闢空間,並且把空間清零 init 初始化 為0 一.棧區 凡是 在函式體內 和 方法體內 定義 的變數 都儲存在棧區 包括形參 棧的特點是 先進後出 先定義的變數 先入棧 後定義的變數後入棧 呼叫函式時 函式中的變數會陸續入棧 函式呼叫結束時...

指標以及記憶體分配

指標很靈活,這使得指標很難管理,在定義指標時,將在棧中開闢一塊記憶體存放指標的位址 棧內的記憶體由系統分配和釋放 指標的位址記憶體只是存放指標的位址,不存放指標指向的資料,值得注意的是,定義指標時指標會隨機指向一塊記憶體,如int p p會指向一塊不為空的記憶體,相當危險,例如執行判斷if p 這裡...

Linux CentOs 記憶體檢視及合理分配

1.檢視總記憶體 grep memtotal proc meminfo 2.檢視可用記憶體及已用記憶體 free free m 預設是以kb為單位,m表示以mb為單位 3.top命令,程序監控 top 進入監控介面後按m後可以看到以記憶體占用大小排序的檢視 4.ps 命令,監控指定的程序 ps e ...