自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解.NET中六個(gè)你必須知道的重要概念

原創(chuàng)
開發(fā) 后端
本文將解釋.Net中的六個(gè)重要概念,它們分別是堆棧,堆,值類型,引用類型,裝箱和拆箱。首先解釋當(dāng)你聲明一個(gè)變量時(shí)在內(nèi)存中會發(fā)生什么,接著介紹兩個(gè)重要的概念堆棧和堆,然后介紹值類型和引用類型,文章最后用例子介紹了裝箱和拆箱對性能的影響。

【51CTO獨(dú)家特稿】我也制作了很多視頻教程,包括設(shè)計(jì)模式,WCF,WWF,WPF,LINQSilverlight,UML,Sharepoint,Azure,VSTS等,可去http://tinyurl.com/mra3hx觀看。

好復(fù)雜的東西啊

圖 1 Oh,My Lady gaga,這些東西好復(fù)雜哦

當(dāng)你聲明一個(gè)變量時(shí)內(nèi)存中都發(fā)生了什么?

當(dāng)你在一個(gè).Net應(yīng)用程序中聲明一個(gè)變量時(shí),首先要分配一些內(nèi)存快到RAM,它包括三樣?xùn)|西,第一個(gè)是變量名,第二個(gè)是變量的數(shù)據(jù)類型,最后一個(gè)是變量的值。

這只是一個(gè)很簡單的解釋,根據(jù)變量的數(shù)據(jù)類型不同,有兩種內(nèi)存分配類型:堆棧內(nèi)存和堆內(nèi)存。

 

聲明變量后的內(nèi)存結(jié)構(gòu)

圖 2 聲明變量后的內(nèi)存結(jié)構(gòu)

堆棧(stack)和堆(heap)

為了幫助理解堆棧和堆,讓我們了解下面的代碼內(nèi)部究竟發(fā)生了什么。

  1. public void Method1()  
  2. {  
  3. // Line 1  
  4. int i=4;  
  5. // Line 2  
  6. int y=2;  
  7. //Line 3  
  8. class1 cls1 = new class1();  

這個(gè)方法內(nèi)部只有三行代碼,下面我就逐行解釋內(nèi)部發(fā)生了什么事情。

第一行:執(zhí)行該行時(shí),編譯器分配一小塊叫做堆棧的內(nèi)存,堆棧負(fù)責(zé)保持跟蹤應(yīng)用程序運(yùn)行需要的內(nèi)存。

第二行:現(xiàn)在執(zhí)行移動到下一步,正如堆棧的名稱所暗示的那樣,這個(gè)內(nèi)存分配時(shí)疊放在前一個(gè)內(nèi)存分配頂部的,你可以將堆棧理解為一系列隔間或盒子的逐層堆積。

內(nèi)存分配和解除分配使用LIFO(Last in first out,后進(jìn)先出)邏輯,換句話說就是內(nèi)存是在內(nèi)存的末尾(如堆棧的頂部)分配和解除分配的。

第三行:在第三行我們創(chuàng)建了一個(gè)對象,執(zhí)行該行時(shí),它在堆棧上創(chuàng)建一個(gè)指針,真實(shí)的對象是存儲一個(gè)不同類型的內(nèi)存分配(叫做堆)中,堆不會跟蹤運(yùn)行的內(nèi)存,它只是對象的堆積,堆用于動態(tài)內(nèi)存分配。

退出方法(有趣):執(zhí)行完最后一行代碼后就該退出這個(gè)方法了,當(dāng)它傳遞結(jié)束控制時(shí),它就會清除分配到堆棧上的所有內(nèi)存變量,換句話說就是所有與int數(shù)據(jù)類型關(guān)聯(lián)的變量按照LIFO方式從堆棧中解除分配。

但不會解除堆內(nèi)存分配,這部分內(nèi)存要通過GARBAGE COLLECTOR(垃圾回收器)解除分配。

 

三行代碼對應(yīng)的內(nèi)存內(nèi)部操作

圖 3 三行代碼對應(yīng)的內(nèi)存內(nèi)部操作

很多人現(xiàn)在可能要問為什么要設(shè)置兩種內(nèi)存分配形式呢?難道就不能用一種內(nèi)存分配形式完成內(nèi)存分配嗎?

如果你仔細(xì)觀察上圖,你就會知道int變量是分配在堆棧上的,因?yàn)榫幾g器已經(jīng)知道它們可以存儲多少數(shù)據(jù)(-2,147,483,648到2,147,483,647),涉及到對象時(shí),編譯器不知道需要多少內(nèi)部空間,因此在堆上分配相同大小的空間。

換句話說就是,如果不知道數(shù)據(jù)大小或是動態(tài)變化的,就需要分配到堆上,如果數(shù)據(jù)大小是確定的,就分配到堆棧上。

 

不知道變量大小時(shí)分配到堆上

 

圖 4 知道變量大小時(shí)分配到堆棧上,不知道變量大小時(shí)分配到堆上

值類型和引用類型

值類型指的是在相同的位置同時(shí)容納數(shù)據(jù)和內(nèi)存的類型,而引用類型是借助一個(gè)指針指向內(nèi)存位置。下面是一個(gè)簡單的命名為i的整數(shù)數(shù)據(jù)類型,其值是由另一個(gè)命名為j的整數(shù)數(shù)據(jù)類型賦予的,這兩個(gè)內(nèi)存值都是基于堆棧分配的。

當(dāng)我們將一個(gè)int值賦給另一個(gè)int值時(shí),它創(chuàng)建一個(gè)完全不同的拷貝,換句話說就是,你修改其中一個(gè)值不會引起另一個(gè)值也發(fā)生變化,這種數(shù)據(jù)類型就叫做值類型。

 

 

值類型

圖 5 值類型:一個(gè)值的變化不會引起另一個(gè)值變化

當(dāng)我們將一個(gè)對象賦值給另一個(gè)對象時(shí),它們指向相同的內(nèi)存位置,如下圖所示,當(dāng)我們將obj賦值給obj1時(shí),它們指向的內(nèi)存位置是一樣的。換句話說就是,如果我們修改了其中一個(gè)對象,另一個(gè)對象也會受到影響,這種類型就叫做引用類型。

 

 

引用類型

圖 6 引用類型:一個(gè)對象的變化會引起另一個(gè)對象的變化

哪一個(gè)數(shù)據(jù)類型是值類型和引用類型呢?

在.Net中,根據(jù)數(shù)據(jù)類型不同,變量可能是基于堆棧分配的,也可能是基于堆分配的,String和Objects是引用類型,其它.Net數(shù)據(jù)類型是基于堆棧分配的,下圖更詳細(xì)地進(jìn)行了解釋。

 

引用類型和值類型對應(yīng)

圖 7 引用類型和值類型對應(yīng).Net中的數(shù)據(jù)類型

#p#

裝箱(boxing)和拆箱(unboxing)

說了這么多,在實(shí)際編程時(shí)怎么使用它們呢?最大的問題是要弄清楚數(shù)據(jù)從堆棧移到堆的性能損失,反之亦然。

如下圖所示,當(dāng)我們將一個(gè)值類型移到引用類型時(shí),數(shù)據(jù)也從堆棧移到堆中,當(dāng)我們將引用類型移到值類型時(shí),數(shù)據(jù)就從堆移到堆棧中。數(shù)據(jù)從堆棧移到堆,或是從堆移到堆棧,都會產(chǎn)生較大的性能損失。數(shù)據(jù)從值類型移到引用類型的過程叫做裝箱,從引用類型移到值類型叫做拆箱。

 

 

 裝箱和拆箱過程示意

圖 8 裝箱和拆箱過程示意

如果你編譯上面的代碼,在相同的ILDASM中,你會看到在IL中的代碼是如何裝箱和拆箱的,如下圖所示。

 

裝箱和拆箱

圖 9 裝箱和拆箱

裝箱和拆箱的性能影響

為了查看性能的影響,我們將下面兩個(gè)函數(shù)運(yùn)行了1000次,如下圖所示,左邊的函數(shù)有裝箱拆箱操作,右邊的函數(shù)沒有,我們使用了一個(gè)秒表對象監(jiān)控所花的時(shí)間。

 

有裝箱拆箱和無裝箱拆箱執(zhí)行時(shí)間對比

圖 10 有裝箱拆箱和無裝箱拆箱執(zhí)行時(shí)間對比

從上圖我們看到,有裝修拆箱需要花3542毫秒,無裝修拆箱只需2477毫秒,因此對性能的影響還是蠻大的。

現(xiàn)在你對這兩個(gè)重要的.Net概念是否都理解了呢?

原文名:6 important .NET concepts: - Stack, heap, Value types, reference types, boxing and Unboxing.

【編輯推薦】

  1. Visual Studio 2010及.Net 4新功能一覽
  2. 升級Visual Studio 2010和.Net 4注意要點(diǎn)
  3. 觀點(diǎn):微軟.NET各子技術(shù)領(lǐng)域的應(yīng)用前景
  4. 三方面詮釋.NET 4.0的新特性
  5. Java和.NET繼續(xù)爭斗的四大相關(guān)問題
責(zé)任編輯:彭凡 來源: 51CTO
相關(guān)推薦

2009-06-04 10:20:34

Hibernate持久化Java

2024-01-08 16:27:59

ES6函數(shù)

2011-05-11 15:28:05

2012-09-29 09:22:24

.NETGC內(nèi)存分配

2012-09-29 10:29:56

.Net內(nèi)存分配繼承

2023-06-26 23:32:11

人工智能Chat GPT工具

2015-07-23 10:37:13

Linux命令

2011-01-28 15:11:15

PowerShell

2019-11-12 14:18:56

PythonWord設(shè)計(jì)

2022-10-25 18:46:36

JavaScript

2017-12-07 15:47:25

2020-02-28 14:05:00

Linuxshell命令

2017-12-07 15:28:36

2019-01-08 10:29:12

BeautifulSoPython第三庫

2021-09-15 09:20:37

Python函數(shù)代碼

2022-09-06 08:07:24

SQL語句查詢

2015-10-27 10:22:47

Html5API調(diào)用

2021-10-29 08:44:22

推拉機(jī)制面試broker

2011-11-30 09:09:13

王濤Windows Pho移動開發(fā)

2015-06-29 09:40:10

Rails新特性
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號