欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#運行時相互關(guān)系淺析

 更新時間:2015年10月15日 11:35:00   投稿:lijiao  
這篇文章介紹了C#運行時相互關(guān)系,包括運行時類型、對象、線程棧和托管堆之間的相互關(guān)系,靜態(tài)方法、實例方法和虛方法的區(qū)別等等。

本文主要講述運行時類型、對象、線程棧和托管堆之間的相互關(guān)系,靜態(tài)方法、實例方法和虛方法的區(qū)別,以及內(nèi)存的分配和回收。

線程棧:在一個進程中可能包含多個線程,一個線程在創(chuàng)建的時候,會分配到一個大小1MB大小的棧,棧用于存儲方法的實參、形參以及方法內(nèi)部的局部變量,棧是從高位內(nèi)存地址向地位地址構(gòu)建的,由于棧有先進后出的特點,所以先定義的變量后被回收。

下面來看一個簡單的例子,讓你更了解線程棧

由于線程棧是從高位開始分配內(nèi)存,先分配的我就畫在上面了,在調(diào)用F1();方法時,分配內(nèi)存的順序是:name->n->F2的返回地址->Age->name;回收內(nèi)存的順序當(dāng)然是反過來的。在一個方法中,應(yīng)該包含一些序幕代碼,進行一些初始化工作,還有一些尾聲代碼,等方法執(zhí)行完成之后做一些回收工作。由于方法的返回地址先分配,在方法執(zhí)行完成的時候回到返回地址,遞歸太深就容易出現(xiàn)棧溢出,請看我的《遞歸再一次讓哥震驚了》,因為參數(shù)、局部變量都必須等到方法返回的時候才能回收。

在介紹托管堆之前先看看兩個簡單的類:

publicclassPerson 
{ 
privateintheight; 
publicvoidSetHeight(intheight) 
{ 
this.height = height; 
} 
publicvirtualvoidSay(stringword) { } 
publicstaticstringHead() 
{ 
return"my head"; 
} 
publicstaticintAge = 100; 
} 
publicclassStudent : Person 
{ 
publicoverridevoidSay(stringword) 
{ 
Console.WriteLine(word); 
} 
} 

 

staticvoidMain(string[] args) 
{ 
Person student = newStudent(); 
student.Say("Hello cth"); 
student.SetHeight(172); 
Person.Head(); 
Console.ReadLine(); 
} 

CLR會在第一次訪問一個對象時加載該對象,在這里,定義變量student時會為Person對象在線程棧中分配內(nèi)存,第一次加載嗎,在構(gòu)造一個Student對象之前先要加載Student對象,并為Student類型對象分配內(nèi)存,并構(gòu)建一個Student對象。對象的地址存入線程棧中的局部變量student 中,我們知道類型對象的內(nèi)容包含:類型對象指針、同步索引塊、靜態(tài)字段和方法(靜態(tài)的和非靜態(tài)的),不管是類型對象、還是實例類型都必須有類型對象指針、同步索引塊;我們知道靜態(tài)字段屬于類,被這個類的所有實例共享,當(dāng)然靜態(tài)字段的內(nèi)存是在類型本身中分配的,方法也是類的所有實例共享的,他的內(nèi)存也是在類型本身中分配的,在每一個類型對象中都有一個方法表,類中定義的方法都有一個對應(yīng)的項。

在構(gòu)造一個對象的實例時,只需要為類型對象指針、同步索引塊、該對象的實例字段分配內(nèi)存,對于對象實例來說,類型對象指針可以讓實例訪問類型對象中德靜態(tài)字段、方法等。

Student是線程棧中的定義的一個局部變量,保存Student的一個實例的在托管堆中的地址,所以他可以訪問Student對象中的字段,方法,其實訪問方法是通過類型對象指針訪問類型對象Student中的方法表中對象的項。

Say方法的執(zhí)行過程:變量student指向的是一個Student對象,調(diào)用的當(dāng)然是Student類型對象中的Say方法,盡管在定義student的時候是Person類型,因為他是引用類型,他指向的是托管堆中Student對象的內(nèi)存,然后遍歷該對象的方法表,找到該方法調(diào)用。

特別說明虛方法,JIT在虛方法中加了一些額外的代碼,方法每次調(diào)用的時候都會執(zhí)行這些代碼,這些代碼會檢查發(fā)出調(diào)用的變量,然后根據(jù)這個變量找到其應(yīng)用的對象,然后調(diào)用這個對象的方法,若沒有這些代碼,你覺得CLR是調(diào)用父類的方法還是調(diào)用之類的方法呢,虛方法帶來方便的同時,也多了這些必須的檢查的代碼。

SetHeight方法的執(zhí)行過程:和Say方法前面是一樣,只是在遍歷Student對象的方法表時沒有找到該方法,我們知道父類中定義的非private方法都可以被子類繼承,是因為每個類型都定義了一個字段引用了他的基類,如果一個類調(diào)用的方法那個方法不是自己定義的,那么編譯器會回溯類層次結(jié)構(gòu),一直到基類Object,找到相關(guān)的方法并調(diào)用,如果沒有找到相關(guān)的方法就報了異常唄。所以SetHeight方法其實調(diào)用的是Person中的SetHeight方法。

Head方法的執(zhí)行:由于Head方法是靜態(tài)方法和上面兩個方法有所不同,調(diào)用靜態(tài)方法的時候,CLR會定位與靜態(tài)方法對象的類型對象,然后在對應(yīng)實例對象對象的方法表中查找相關(guān)的記錄項,如果沒有找到,同樣會回溯。

當(dāng)執(zhí)行完student.SetHeight(172);時,student在也沒有被引用,成為垃圾,在其所在的方法返回之前將會被回收,也就是說student實例對象被回收,釋放其所在的內(nèi)存,而類型對象不會被回收,類型對象的生成周期是:對象被加載到CLR中,直到其所在的AppDomain卸載。靜態(tài)字段是他所引用類型的跟,所以被靜態(tài)類型引用的對象永遠不會被回收,如果其引用的是一個集合對象,并向其中不斷的加入元素的話,就會造成內(nèi)存泄露。

以上就是關(guān)于C#運行時相互關(guān)系的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • c# dynamic的好處

    c# dynamic的好處

    這篇文章主要介紹了c# dynamic的好處,以示例代碼幫助大家更好的了解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-12-12
  • c#中利用Tu Share獲取股票交易信息

    c#中利用Tu Share獲取股票交易信息

    這篇文章主要介紹了c#中利用Tu Share獲取股票交易信息,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • C#設(shè)計模式之觀察者模式實例講解

    C#設(shè)計模式之觀察者模式實例講解

    這篇文章主要介紹了C#設(shè)計模式之觀察者模式實例講解,本文詳細講解了觀察者模式的定義、優(yōu)缺點、代碼實例等,需要的朋友可以參考下
    2014-10-10
  • C#開源的AOP框架--KingAOP基礎(chǔ)

    C#開源的AOP框架--KingAOP基礎(chǔ)

    這篇文章主要介紹了一款C#開源的AOP框架--KingAOP框架的基礎(chǔ)知識,對于想學(xué)習(xí)AOP的小伙伴來說,非常不錯,希望大家能夠喜歡。
    2015-12-12
  • Question:基于C#連續(xù)賦值的面試題(解答)

    Question:基于C#連續(xù)賦值的面試題(解答)

    本篇文章是對C#中連續(xù)賦值的面試題進行了解答,需要的朋友參考下
    2013-05-05
  • C#使用windows服務(wù)開啟應(yīng)用程序的方法

    C#使用windows服務(wù)開啟應(yīng)用程序的方法

    這篇文章主要介紹了C#使用windows服務(wù)開啟應(yīng)用程序的方法,實例分析了C#操作windows服務(wù)開啟應(yīng)用程序所遇到的問題及相關(guān)解決技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • winform c#中子窗體關(guān)閉刷新父窗體的實例

    winform c#中子窗體關(guān)閉刷新父窗體的實例

    下面小編就為大家?guī)硪黄獁inform c#中子窗體關(guān)閉刷新父窗體的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 一文帶你快速學(xué)會C#中WinForm框架的使用詳解

    一文帶你快速學(xué)會C#中WinForm框架的使用詳解

    WinForm是一門非常經(jīng)濟實惠的技術(shù),就是說,可以在短時間內(nèi)學(xué)會,并迅速借此進行項目開發(fā)。本文就來和大家聊聊WinForm框架的使用方法,希望對大家有所幫助
    2023-02-02
  • C#判斷字符串是否是int/double(實例)

    C#判斷字符串是否是int/double(實例)

    本文主要分享了C#判斷字符串是否是int/double的具體實例,具有一定的參考價值,需要的朋友一起來看下吧
    2016-12-12
  • WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析

    WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析

    這篇文章主要介紹了WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析,對C#初學(xué)者來說很有學(xué)習(xí)借鑒價值,需要的朋友可以參考下
    2014-08-08

最新評論