熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

c#基礎學習之內存管理

2022-06-13   來源: .NET編程 

  正式學習c#ASPNET已經有半年多了期間一直在忙一個項目很少有時間能夠看看基礎知識前兩天看到一貼子突然發現自己的基礎知識是如此的薄弱很多問題是知其然不知其所以然基礎知識的缺失注定達不到你所想要的高度因此現在想抽出時間來看看基礎但是自己有不想再去一頁一頁的看那本那麼厚的《c#高級編程》和《ASPNET高級編程》所以想到什麼地方就看什麼地方了不求順序但求效果

  然看了書後自己就想寫點什麼一是加深理解和印象二是和園友們共同探討自己從來沒有寫過系列文章就從這裡開始吧雖然都是寫基礎的東西對高手來說都是再簡單不過了但對我這樣的新手來說基礎的才是最重要的

  於是就寫這個系列

  內存管理

  c#編程的一個優點是程序員不需要關心具體的內存管理尤其是垃圾收集器會處理所有的內存清理工作雖然不必手工管理內存但如果要編寫高質量的代碼還是要理解後台發生的事情理解c#的內存管理本文主要介紹給變量分配內存時計算機內存中發生的情況

  c#將數據分為兩種值數據類型和引用數據類型這兩種數據類型存儲在內存中的不同的地方值數據類型存儲在堆棧中而引用類型存儲在內存的托管堆中

  內存簡介

  Windows使用一個系統虛擬尋址系統這個系統的作用是將程序可用的內存地址映射到硬件內存中的實際地址上其實際結果就是位的機子上每個進程都可以使用GB的內存當然位機這個數字就大了去了GB的內存實際上包含了程序的所有的部分可執行代碼DLL以及程序運行時使用的所有變量的內容這個GB的內存成為虛擬地址空間或虛擬內存為方便這裡成為內存

  GB中的每個存儲單元都是從零開始向上存儲的要訪問存儲在內存中的某個空間中的值就必須提供表示該存儲單元的一個數字在高級編程語言中編譯器的一個重要作用就是負責將人們可以理解的變量名稱變為處理器可以理解的內存地址

  堆棧

  在內存中有一個區域成為堆棧存儲對象

  對象成員的值數據類型調用方法時傳遞給所有方法的參數的副本注意調用方法時堆棧存儲的是所有參數的副本因此經值類型A傳遞給函數A的值是不會變化的當然引用類型是會變化的因為在堆棧中存儲的是引用類型的地址這在後面會有詳細的介紹

  下面以一個例子來說明堆棧的工作方式如下面的代碼  : {
: int a;
: //do something;
: {
: int b;
: //do something
: }
: }

  首先聲明a在內部的代碼塊中聲明b然後內部的代碼塊終止b就出了作用域最後a出作用域所以b的生命周期總是包含在a的生命周期內在釋放變量的時候其順序總是和分配內存的順序是相反的變量的生存周期都是嵌套的這就是堆棧的工作方式

  托管堆

  堆棧具有相當高的性能但是變量的生命周期必須是嵌套的這個要求在有的時候過於苛刻我們希望有一種別的方法來分配內存存儲一些數據並在方法退出的很長一段時間內這些數據仍然是可用的這時就使用托管堆

  托管堆(簡稱堆)是內存中的另外一個區域我們仍然用一個例子來說明堆的工作方式如下面代碼  : {
: Customer customer;
: customer=new Customer();
: Customer customer=new Customer();
: //do something
: }

  首先聲明一個Customercustomer在堆棧上給這個引用分配存儲控件請注意僅僅是給這個引用分配存儲空間並不是實際的Customer對象customer占用個字節的空間(位機)來表示Customer對象在內存中的地址

  然後執行第二行代碼完成以下操作

  在堆上分配存儲空間用來存儲Customer對象注意這裡是Customer對像

  將變量customer的值設為分配給Customer對象的內存地址從這個例子中可以看出建立引用類型的變量的過程要比獎勵值類型變量的過程復雜且不避免的有性能的降低但是我們可以將一個引用變量的值賦給另一個引用變量當一個變量出作用域時它會從堆棧中刪除但是對象的數據仍然保留在內存中知道程序停止

  這樣我們在將一個引用變量A傳遞給函數時僅僅是將變量A的引用傳遞給了函數僅僅是在堆棧上分配內存即變量B兩者指向同一個內存地址因此當變量B發生變化時變量A也會發生變化

  裝箱和拆箱

  裝箱和拆箱就是值類型和引用類型的項目轉化裝箱可以將值類型轉化為引用類型拆箱的作用正好相反經引用類型轉化為值類型

  垃圾收集

  一般情況下NET運行庫會在認為需要的時候運行垃圾收集器來釋放托管資源這在大多數情況下足夠了就是說我們沒有必要去關心內存但在有的情況下我們會強制垃圾回收集器在代碼的某個地方運行釋放內存這就用到了SystemGCCollect()SystemGC表示一個垃圾收集器這種情況很少例如代碼中大量的對象剛剛停止引用就適合調用垃圾收集器


From:http://tw.wingwit.com/Article/program/net/201311/11779.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.