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

C#中Array的存儲(chǔ)結(jié)構(gòu)簡(jiǎn)單介紹

 更新時(shí)間:2023年11月23日 09:17:16   作者:彭_澤  
本文將從一個(gè)數(shù)組的基礎(chǔ)操作開(kāi)始,逐步來(lái)推導(dǎo)數(shù)組的在C#基礎(chǔ)操作、數(shù)組在CoreCLR的維護(hù)策略,數(shù)組在C++的內(nèi)存分配等階段具體是如何實(shí)現(xiàn)的,感興趣的朋友跟隨小編一起看看吧

數(shù)組是C#中最基礎(chǔ)的存儲(chǔ)結(jié)構(gòu)之一,很多的存儲(chǔ)結(jié)構(gòu)其底層的實(shí)現(xiàn)中都是基于數(shù)組實(shí)現(xiàn)的,如:List、Queue、Stack、Dictionary、Heap等等,如果大家讀過(guò)這些類型的底層實(shí)現(xiàn)源碼,其實(shí)就可以發(fā)現(xiàn),這些存儲(chǔ)結(jié)構(gòu)都是在其內(nèi)部維護(hù)了一個(gè)或多個(gè)數(shù)組。本文重點(diǎn)來(lái)學(xué)習(xí)一下數(shù)組存儲(chǔ)結(jié)構(gòu)的實(shí)現(xiàn)邏輯。

  首先,我們來(lái)看看數(shù)組的定義:靜態(tài)數(shù)組是由相同類型的元素線性排列的數(shù)據(jù)結(jié)構(gòu),在計(jì)算機(jī)上會(huì)分配一段連續(xù)的內(nèi)存,對(duì)元素進(jìn)行順序存儲(chǔ)。從以上的描述中,我們可以發(fā)現(xiàn)幾個(gè)征:"相同類型、連續(xù)內(nèi)存、順序存儲(chǔ)",這樣的結(jié)構(gòu)特性,可以能做到基于下標(biāo),對(duì)數(shù)組進(jìn)行 O(1) 時(shí)間復(fù)雜度的快速隨機(jī)訪問(wèn)。

  那么數(shù)組為什么可以做到快速隨機(jī)訪問(wèn)?我們可以先來(lái)簡(jiǎn)單的說(shuō)明一下,"存儲(chǔ)數(shù)組時(shí),會(huì)事先分配一段連續(xù)的內(nèi)存空間,將數(shù)組元素依次存入內(nèi)存。因?yàn)閿?shù)組元素的類型都是一樣的,所以每個(gè)元素占用的空間大小也是一樣的,這樣我們就很容易用“數(shù)組的開(kāi)始地址 +index* 元素大小”的計(jì)算方式,快速定位到指定索引位置的元素,這也是數(shù)組基于下標(biāo)隨機(jī)訪問(wèn)的復(fù)雜度為 O(1) 的原因。"這樣的描述可能是絕大部分同學(xué)都有所接觸到的內(nèi)容,并且也能讓大家大致的了解到其存儲(chǔ)原理,但是C#數(shù)組的存儲(chǔ)結(jié)構(gòu)是如何具體實(shí)現(xiàn)的呢?

  本文將從一個(gè)數(shù)組的基礎(chǔ)操作開(kāi)始,逐步來(lái)推導(dǎo)數(shù)組的在C#基礎(chǔ)操作、數(shù)組在CoreCLR的維護(hù)策略,數(shù)組在C++的內(nèi)存分配等階段具體是如何實(shí)現(xiàn)的。

  首先,我們先來(lái)看一個(gè)簡(jiǎn)單的數(shù)組定義、初始化、賦值、取值的過(guò)程。

int[] myIntArray = new int[5] { 1, 2, 3, 4, 5 };
        for (int j = 0; j < 10; j++ )
        {
           Console.WriteLine("Element[{0}] = {1}", j, myIntArray[j]);
        }

  這個(gè)過(guò)程中具體的實(shí)現(xiàn)邏輯什么樣的呢,對(duì)于C#數(shù)組在內(nèi)存的存儲(chǔ)方式、數(shù)組的Cpoy、動(dòng)態(tài)數(shù)組的擴(kuò)容機(jī)制是什么樣的呢?在C#中Array充當(dāng)數(shù)組的基類,用于創(chuàng)建、處理、搜索數(shù)組并對(duì)數(shù)組進(jìn)行排序,但是只有系統(tǒng)和編譯器才能顯式從Array類派生。接下來(lái)我們就來(lái)了解一下Array底層源碼實(shí)現(xiàn)。對(duì)于數(shù)組的初始化,我們使用以上示例中的int[]進(jìn)行介紹。在C#中所有的數(shù)組類型都集成自抽象類Array,在對(duì)int[]初始化的過(guò)程中,都會(huì)使用array的CreateInstance()方法,該方法存在多個(gè)重載,主要區(qū)別為用于創(chuàng)建一維、二維、三維等不同維數(shù)的數(shù)組結(jié)構(gòu),以下我們來(lái)看一下對(duì)于一維數(shù)據(jù)的創(chuàng)建代碼。

public static unsafe Array CreateInstance(Type elementType, int length)
        {
            RuntimeType? t = elementType.UnderlyingSystemType as RuntimeType;
            return InternalCreate(t, 1, &length, null);
        }

  上面的代碼中,我們可以發(fā)現(xiàn)兩個(gè)地方需要關(guān)注,第一部分:RuntimeType? t = elementType.UnderlyingSystemType as RuntimeType;該方法獲取數(shù)組元素類型的基礎(chǔ)系統(tǒng)類型,并將其轉(zhuǎn)換為 RuntimeType。第二部分:InternalCreate(t, 1, &length, null)具體創(chuàng)建數(shù)組的操作,我們來(lái)看一下其實(shí)現(xiàn)的源碼。(源碼進(jìn)行部分刪減)

private static unsafe Array InternalCreate(RuntimeType elementType, int rank, int* pLengths, int* pLowerBounds)
        {
            if (rank == 1)
            {
                return RuntimeImports.RhNewArray(elementType.MakeArrayType().TypeHandle.ToEETypePtr(), pLengths[0]);
            }
            else
            {
                int* pImmutableLengths = stackalloc int[rank];
                for (int i = 0; i < rank; i++) pImmutableLengths[i] = pLengths[i];
                return NewMultiDimArray(elementType.MakeArrayType(rank).TypeHandle.ToEETypePtr(), pImmutableLengths, rank);
            }
        }

  該方法用于在運(yùn)行時(shí)創(chuàng)建數(shù)組,其中參數(shù)elementType表示數(shù)組元素運(yùn)行時(shí)的類型,rank表示數(shù)組的維度,pLengths表示指向數(shù)組長(zhǎng)度的指針,pLowerBounds表示指向數(shù)組下限(如果有的話)的指針。根據(jù)設(shè)定的rank的值,創(chuàng)建一維或多維數(shù)組。其中elementType.MakeArrayType().TypeHandle.ToEETypePtr()表示先將當(dāng)前type 對(duì)象表示的類型通過(guò) MakeArrayType 方法創(chuàng)建一個(gè)數(shù)組類型,然后獲取該數(shù)組類型的運(yùn)行時(shí)類型句柄,最后通過(guò) ToEETypePtr 方法將運(yùn)行時(shí)類型句柄轉(zhuǎn)換為指向類型信息的指針。我們先看一下創(chuàng)建一維數(shù)組的邏輯,具體代碼如下:

[MethodImpl(MethodImplOptions.InternalCall)]
        [RuntimeImport(RuntimeLibrary, "RhNewArray")]
        private static extern unsafe Array RhNewArray(MethodTable* pEEType, int length);
        internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) => RhNewArray(pEEType.ToPointer(), length);

  該方法是具體實(shí)現(xiàn)數(shù)組創(chuàng)建的邏輯,我們先來(lái)看一下參數(shù),其中EETypePtr是CLR中用于表示對(duì)象類型信息的指針類型。每個(gè).NET對(duì)象在運(yùn)行時(shí)都關(guān)聯(lián)有一EEType結(jié)構(gòu),它包含有關(guān)對(duì)象類型的信息,例如該類型的方法表、字段布局、基類信息等。

  這里簡(jiǎn)單的介紹一下代碼上面的兩個(gè)自定義屬性:

(1)、[MethodImpl(MethodImplOptions.InternalCall)] 
   指示編譯器生成的方法體會(huì)被一個(gè)外部實(shí)現(xiàn)取代,而該外部實(shí)現(xiàn)通常由運(yùn)行時(shí)環(huán)境提供。
(2)、[RuntimeImport(RuntimeLibrary, "RhNewArray")] 
    這是一個(gè)自定義的特性,在項(xiàng)目中定義的用于指示運(yùn)行時(shí)導(dǎo)入的特性。 
在C#中,使用屬性標(biāo)記運(yùn)行時(shí)導(dǎo)入的位置通常是為了提供額外的元數(shù)據(jù)和信息,以告訴編譯器和運(yùn)行時(shí)環(huán)境如何正確地處理外部方法的調(diào)用。

  使用屬性標(biāo)記運(yùn)行時(shí)導(dǎo)入的主要目的有以下幾點(diǎn):

(1)、元數(shù)據(jù)信息:運(yùn)行時(shí)導(dǎo)入的位置可能包括一些元數(shù)據(jù)信息,如函數(shù)名稱、庫(kù)名稱、調(diào)用約定等。     使用屬性可以將這些信息嵌入到C#代碼中,使得代碼更加自解釋,并提供足夠的信息供編譯器和運(yùn)行時(shí)使用。 
(2)、優(yōu)化和安全性:編譯器和運(yùn)行時(shí)環(huán)境可能會(huì)使用屬性來(lái)進(jìn)行性能優(yōu)化或安全性檢查。 例如,通過(guò)指定調(diào)用約定或其他屬性,可以幫助編譯器生成更有效的代碼。 
(3)、與運(yùn)行時(shí)環(huán)境交互:屬性可以提供一種與底層運(yùn)行時(shí)環(huán)境進(jìn)行交互的機(jī)制。 例如,通過(guò)自定義屬性,可以向運(yùn)行時(shí)環(huán)境傳遞一些特殊的標(biāo)志或信息,以影響方法的行為。
(4)、代碼維護(hù)和可讀性:使用屬性可以提高代碼的可維護(hù)性和可讀性。 在代碼中使用屬性來(lái)標(biāo)記運(yùn)行時(shí)導(dǎo)入的位置,使得代碼的意圖更加清晰,也有助于團(tuán)隊(duì)協(xié)作。

  在CLR的內(nèi)部,EETypePtr是一個(gè)指向EEType結(jié)構(gòu)的指針,其中EEType是運(yùn)行時(shí)中用于描述對(duì)象類型的結(jié)構(gòu)。EEType結(jié)構(gòu)的內(nèi)容由運(yùn)行時(shí)系統(tǒng)生成和管理,而EETypePtr則是對(duì)這個(gè)結(jié)構(gòu)的指針引用。根據(jù)傳入的運(yùn)行時(shí)對(duì)象類型進(jìn)行處理,我們接下來(lái)看一下pEEType.ToPointer()的實(shí)現(xiàn)。

 internal unsafe Internal.Runtime.MethodTable* ToPointer()
         {
             return (Internal.Runtime.MethodTable*)(void*)_value;
        }

  ToPointer()方法目的是將其對(duì)象或值轉(zhuǎn)換為指針,MethodTable 是CLR用于管理類和對(duì)象的元數(shù)據(jù),用于存儲(chǔ)類型相關(guān)信息的數(shù)據(jù)結(jié)構(gòu),每個(gè)對(duì)象在內(nèi)存中都包含一個(gè)指向其類型信息的指針,這個(gè)指針指向該類型的 MethodTable,用于支持CLR在運(yùn)行時(shí)進(jìn)行類型檢查、虛方法調(diào)用等操作。那我們來(lái)具體看一下MethodTable的數(shù)據(jù)結(jié)構(gòu)。

struct MethodTable
        {
            // 指向類型的虛方法表(VTable)
            IntPtr* VirtualMethodTable;
            // 字段表
            FieldInfo* Fields;
            // 接口表
            InterfaceInfo* Interfaces;
            // 其他元數(shù)據(jù)信息...
        }

  我們從原始的數(shù)組初始化和賦值,一直推導(dǎo)至對(duì)象的數(shù)組空間維護(hù)。截止當(dāng)前,我們獲取到數(shù)組的MethodTable* pEEType數(shù)據(jù)結(jié)構(gòu)。接下來(lái)我們來(lái)看一下CLR對(duì)數(shù)組的內(nèi)存空間分配邏輯和維護(hù)方案。由于CoreCLR中的實(shí)現(xiàn)代碼我們沒(méi)有辦法全面的了解,我們接下按照預(yù)定的邏輯進(jìn)行一定的推論。(CCoreCLR的實(shí)現(xiàn)代碼絕大部分是使用C++實(shí)現(xiàn))

#include <cstdint>
extern "C" {
    struct MethodTable { // 方法表等信息...};
    struct Array { // 數(shù)組相關(guān)信息...};
    void* RhNewArray(void* pEEType, int length) {
        // 假設(shè)存在一個(gè)用于對(duì)象分配的函數(shù),該函數(shù)分配數(shù)組的內(nèi)存
        void* rawArrayMemory = AllocationFunction(length * sizeof(Array));
        // 將傳遞的 pEEType 信息保存到數(shù)組對(duì)象中
        Array* newArray = static_cast<Array*>(rawArrayMemory);
        //為數(shù)組對(duì)象設(shè)置元數(shù)據(jù)信息
        newArray->MethodTablePointer = pEEType;
        return rawArrayMemory;
    }
}

  以上代碼是一種假設(shè)實(shí)現(xiàn)方式, AllocationFunction 的函數(shù)用于內(nèi)存分配,并且數(shù)組對(duì)象(Array)有一個(gè)成員 MethodTablePointer 用于存儲(chǔ) MethodTable 的指針。接下來(lái)我們?cè)賮?lái)看一下AllocationFunction()方法推測(cè)實(shí)現(xiàn)邏輯。

void* AllocationFunction(size_t size) {
    // 使用標(biāo)準(zhǔn)庫(kù)的 malloc 函數(shù)進(jìn)行內(nèi)存分配
    void* memory = malloc(size);
    //處理內(nèi)存分配失敗的情況
    ...
    return memory;
}

  以上的代碼中,使用標(biāo)準(zhǔn)函數(shù)庫(kù)malloc()進(jìn)行內(nèi)存的分配,malloc ()是C標(biāo)準(zhǔn)庫(kù)中的一個(gè)函數(shù),用于在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存。malloc ()接受一個(gè) size 參數(shù),表示要分配的內(nèi)存字節(jié)數(shù)。它返回一個(gè)指向分配內(nèi)存起始地址的指針,或者在分配失敗時(shí)返回 NULL。malloc ()內(nèi)存分配邏輯通常涉及以下步驟:

(1)、請(qǐng)求內(nèi)存空間: malloc() 根據(jù)傳遞的 size 參數(shù)向系統(tǒng)請(qǐng)求一塊足夠大的內(nèi)存空間。 (2)、內(nèi)存分配:如果系統(tǒng)成功分配了請(qǐng)求的內(nèi)存塊,malloc 會(huì)在這塊內(nèi)存中標(biāo)記已分配的部分,并將其起始地址返回給調(diào)用者。 
(3)、返回結(jié)果:如果分配成功,malloc 返回一個(gè)指向新分配內(nèi)存的指針。如果分配失敗(例如,系統(tǒng)內(nèi)存不足),則返回 NULL。
(4)、內(nèi)存對(duì)齊:部分系統(tǒng)要求分配的內(nèi)存是按照特定字節(jié)對(duì)齊的。因此,malloc 通常會(huì)確保返回的內(nèi)存地址滿足系統(tǒng)的對(duì)齊要求。 
(5)、初始化內(nèi)存:malloc 返回的內(nèi)存通常不會(huì)被初始化,即其中的數(shù)據(jù)可能是未知的。在使用之前,需要通過(guò)其他手段對(duì)內(nèi)存進(jìn)行初始化。 
(6)、內(nèi)存管理:一些實(shí)現(xiàn)可能會(huì)使用內(nèi)部數(shù)據(jù)結(jié)構(gòu)來(lái)跟蹤已分配和未分配的內(nèi)存塊,以便在 free 被調(diào)用時(shí)能夠釋放相應(yīng)的內(nèi)存。

  以上簡(jiǎn)單的描述了C++在底層實(shí)現(xiàn)內(nèi)存分配的簡(jiǎn)單實(shí)現(xiàn)方式,對(duì)于CoreCLRe中對(duì)于數(shù)組的內(nèi)存空間申請(qǐng)相對(duì)非常復(fù)雜,可能涉及內(nèi)存池、分配策略、對(duì)齊要求等方面的考慮。后續(xù)有機(jī)會(huì)再做詳細(xì)的介紹。既然說(shuō)到CoreCLR的內(nèi)存實(shí)現(xiàn)為C++的內(nèi)存分配策略,那我們接下來(lái)看一下其對(duì)應(yīng)的常用策略管理策略。我們用一個(gè)簡(jiǎn)單的數(shù)組的內(nèi)存分配。

int myArray[5]; // 聲明一個(gè)包含5個(gè)整數(shù)的數(shù)組
 +------+------+------+------+------+
 | int0 | int1 | int2 | int3 | int4 |
+------+------+------+------+------+

  myArray 是整個(gè)數(shù)組的起始地址,然后每個(gè) int 元素按照其大小排列在一起?;谝陨系姆治觯覀兛梢钥吹紺++對(duì)于內(nèi)存的分配概述大致如下:

(1)、元素的內(nèi)存布局:數(shù)組的元素在內(nèi)存中是依次排列的,每個(gè)元素占用的內(nèi)存空間由元素的類型決定。     例如,一個(gè) int 數(shù)組中的每個(gè)整數(shù)元素通常占用4個(gè)字節(jié)(32位系統(tǒng))或8個(gè)字節(jié)(64位系統(tǒng))。 
(2)、數(shù)組的起始地址:數(shù)組的內(nèi)存分配通常從數(shù)組的第一個(gè)元素開(kāi)始。數(shù)組的起始地址是數(shù)組第一個(gè)元素的地址。 
(3)、連續(xù)存儲(chǔ):數(shù)組的元素在內(nèi)存中是連續(xù)存儲(chǔ)的,這意味著數(shù)組中的每個(gè)元素都直接跟在前一個(gè)元素的后面。

  上面介紹了內(nèi)存空間的分配,我們接下來(lái)看一下這段代碼的實(shí)現(xiàn)邏輯,rawArrayMemory: 這是一個(gè) void* 類型的指針,通常指向分配的內(nèi)存塊的起始位置。static_cast 運(yùn)算符,將 rawArrayMemory 從 void* 類型轉(zhuǎn)換為 Array* 類型。

  Array* newArray = static_cast<Array*>(rawArrayMemory);

  我們從以上對(duì)于數(shù)組的創(chuàng)建過(guò)程中,分析了C#、CoreCLR、C++等多個(gè)實(shí)現(xiàn)視角進(jìn)行了簡(jiǎn)單的分析。

  接下來(lái)我們回歸到CoreCLR中對(duì)于數(shù)組的內(nèi)存空間管理策略,數(shù)組內(nèi)存分配的常用步驟:

1、分配對(duì)象頭:為數(shù)組對(duì)象分配對(duì)象頭,對(duì)象頭包含一些元數(shù)據(jù),如類型指針、同步塊索引等信息。
2、分配數(shù)組元素空間:分配存儲(chǔ)數(shù)組元素的內(nèi)存塊,這是實(shí)際存儲(chǔ)數(shù)組數(shù)據(jù)的地方。
3、初始化數(shù)組元素:根據(jù)數(shù)組類型的要求,初始化數(shù)組元素。這可能涉及到對(duì)元素進(jìn)行默認(rèn)初始化,例如將整數(shù)數(shù)組的每個(gè)元素初始化為零。
4、返回?cái)?shù)組引用:返回指向數(shù)組對(duì)象的引用,使得該數(shù)組可以被使用。

  當(dāng)我們?cè)谕泄艽a中聲明一個(gè)數(shù)組時(shí),CoreCLR會(huì)在托管堆上動(dòng)態(tài)分配內(nèi)存,以存儲(chǔ)數(shù)組的元素,并在分配的內(nèi)存塊中存儲(chǔ)有關(guān)數(shù)組的元數(shù)據(jù),這些元數(shù)據(jù)通常包括數(shù)組的長(zhǎng)度和元素類型等信息。CoreCLR通常會(huì)對(duì)分配的內(nèi)存進(jìn)行對(duì)齊,以提高訪問(wèn)效率,這可能導(dǎo)致分配的內(nèi)存塊略大于數(shù)組元素的實(shí)際大小。可能有同學(xué)會(huì)問(wèn)為什么要進(jìn)行內(nèi)存的對(duì)齊,這里就簡(jiǎn)單的說(shuō)明一下。

1、硬件要求:訪問(wèn)特定類型的數(shù)據(jù)時(shí),其地址應(yīng)該是某個(gè)值的倍數(shù)。

2、提高訪問(wèn)速度:對(duì)齊的內(nèi)存訪問(wèn)通常比不對(duì)齊的訪問(wèn)更加高效。處理器通常能夠更快地訪問(wèn)對(duì)齊的內(nèi)存,因?yàn)檫@符合硬件訪問(wèn)模式。

3、減少內(nèi)存碎片:內(nèi)存對(duì)齊還有助于減少內(nèi)存碎片,使得內(nèi)存的使用更加緊湊。內(nèi)存碎片可能導(dǎo)致性能下降,因?yàn)樗赡茉黾恿朔峙浜歪尫艃?nèi)存的開(kāi)銷。

4、硬件事務(wù):一些處理器和操作系統(tǒng)支持原子操作,但通常要求數(shù)據(jù)是按照特定的對(duì)齊方式排列的。

  上面介紹了為什么需要進(jìn)行內(nèi)存對(duì)齊,那么對(duì)于CoreCLR的內(nèi)部實(shí)現(xiàn)是如何進(jìn)行內(nèi)存對(duì)齊的呢?我們簡(jiǎn)潔的介紹一下實(shí)現(xiàn)大流程:

1、使用操作系統(tǒng)的內(nèi)存分配函數(shù):使用操作系統(tǒng)提供的內(nèi)存分配函數(shù)來(lái)分配托管堆上的內(nèi)存。在Windows上可能是HeapAlloc。

2、對(duì)齊方式的指定:在調(diào)用內(nèi)存分配函數(shù)時(shí),會(huì)指定所需的對(duì)齊方式。通常是以字節(jié)為單位的對(duì)齊值。常見(jiàn)的對(duì)齊值包括4字節(jié)、8字節(jié)等。

3、內(nèi)存塊的對(duì)齊:內(nèi)存分配函數(shù)返回的內(nèi)存塊通常是按照指定的對(duì)齊方式進(jìn)行對(duì)齊的。CLR確保返回的內(nèi)存塊的起始地址符合對(duì)齊規(guī)則。

4、對(duì)齊規(guī)則的維護(hù):維護(hù)對(duì)齊規(guī)則的信息,確保在托管堆上分配和釋放的內(nèi)存塊都符合相同的對(duì)齊方式。

5、內(nèi)存對(duì)齊的優(yōu)化:對(duì)內(nèi)存對(duì)齊進(jìn)行一些優(yōu)化,以提高訪問(wèn)效率。例如,它可以在對(duì)象的布局中考慮對(duì)齊規(guī)則,以減少內(nèi)存碎片。

  具體的數(shù)組內(nèi)存分配策略可能會(huì)因CLR的版本和實(shí)現(xiàn)而異。不同的垃圾回收算法(如標(biāo)記-清除、復(fù)制、標(biāo)記-整理等)以及不同的GC代(新生代、老年代)也可能影響內(nèi)存分配的具體實(shí)現(xiàn)。在.NET中,CLR提供了不同的垃圾回收器實(shí)現(xiàn),例如Workstation GC和Server GC。Workstation GC通常適用于單處理器或少量處理器的環(huán)境,而Server GC適用于多處理器環(huán)境。這些GC實(shí)現(xiàn)可能在內(nèi)存分配和回收方面有一些差異。

  本文借助了一個(gè)數(shù)組的初始化和賦值為樣例,逐層的分析了數(shù)組對(duì)象運(yùn)行時(shí)結(jié)構(gòu)的獲取、對(duì)象MethodTable結(jié)構(gòu)的分析、CoreCLR底層對(duì)數(shù)組內(nèi)存結(jié)構(gòu)的創(chuàng)建推導(dǎo)、C++對(duì)于內(nèi)存的分配策略等視角,最后還綜合的介紹了CoreCLR對(duì)于數(shù)組內(nèi)存的創(chuàng)建步驟。

  我們一直以來(lái)對(duì)于數(shù)組的內(nèi)存分配,都有一個(gè)整體的認(rèn)識(shí),其特點(diǎn)是"相同類型、連續(xù)內(nèi)存、順序存儲(chǔ)",對(duì)于其連續(xù)內(nèi)存的特點(diǎn)記憶深刻,但是在內(nèi)部如何實(shí)現(xiàn)進(jìn)行的連續(xù)內(nèi)存卻沒(méi)有整體的了解,C#內(nèi)部是如何完成不同類型對(duì)象數(shù)組的運(yùn)行時(shí)創(chuàng)建,在CoreCLR內(nèi)部如何進(jìn)行內(nèi)存的劃分是沒(méi)有做過(guò)了解和推導(dǎo),甚至于CoreCLR內(nèi)部是如何維護(hù)一個(gè)對(duì)象的結(jié)構(gòu),很多時(shí)候都只是了解到運(yùn)行時(shí)對(duì)象使用Type類型就可以得到,那么CoreCLR內(nèi)部如何來(lái)維護(hù)這個(gè)Type呢?其實(shí)很多時(shí)候沒(méi)有特點(diǎn)去了解過(guò)其結(jié)構(gòu)。

  以上內(nèi)容是對(duì)C#中Array的存儲(chǔ)結(jié)構(gòu)的簡(jiǎn)單介紹,如錯(cuò)漏的地方,還望指正。

到此這篇關(guān)于深度分析C#中Array的存儲(chǔ)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)C# Array存儲(chǔ)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#使用動(dòng)態(tài)規(guī)劃解決0-1背包問(wèn)題實(shí)例分析

    C#使用動(dòng)態(tài)規(guī)劃解決0-1背包問(wèn)題實(shí)例分析

    這篇文章主要介紹了C#使用動(dòng)態(tài)規(guī)劃解決0-1背包問(wèn)題,實(shí)例分析了C#動(dòng)態(tài)規(guī)劃算法的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#中的兩種debug方法介紹

    C#中的兩種debug方法介紹

    這篇文章主要介紹了C#中的兩種debug方法介紹,本文講解了代碼用 #if DEBUG 包裹、利用宏定義兩種方法,需要的朋友可以參考下
    2015-02-02
  • 關(guān)于C# 類和對(duì)象詳情

    關(guān)于C# 類和對(duì)象詳情

    類是C#面向?qū)ο缶幊痰幕締卧?。一個(gè)類都可以包含2種成員:字段和方法,接下來(lái)小編將在文章里向大家詳細(xì)介紹
    2021-09-09
  • C#集合之并發(fā)集合的用法

    C#集合之并發(fā)集合的用法

    這篇文章介紹了C#集合之并發(fā)集合的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 談一談autofac組件的實(shí)例范圍

    談一談autofac組件的實(shí)例范圍

    這篇文章主要和大家聊一聊autofac組件的實(shí)例范圍,探討autofac組件的實(shí)例范圍,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • 詳解C#如何控制多線程同步執(zhí)行

    詳解C#如何控制多線程同步執(zhí)行

    使用Task類來(lái)控制多線程的同步執(zhí)行,可應(yīng)用于多任務(wù)分發(fā)執(zhí)行后,這篇文章主要為大家詳細(xì)介紹了C#如何通過(guò)Task類控制多線程同步執(zhí)行,感興趣的小伙伴可以了解下
    2023-12-12
  • 根據(jù)灰度值填充字符-單文件單線程版

    根據(jù)灰度值填充字符-單文件單線程版

    本文介紹如何實(shí)現(xiàn):類似于一個(gè)圖片,處理后,根據(jù)不同的灰度值,填充不同的字符等相關(guān)功能,感興趣的朋友可以了解下哦
    2013-01-01
  • C#判斷程序是否是管理員權(quán)限運(yùn)行的方法代碼示例

    C#判斷程序是否是管理員權(quán)限運(yùn)行的方法代碼示例

    這篇文章主要介紹了C#判斷程序是否是管理員權(quán)限運(yùn)行的方法代碼示例,本文直接給出實(shí)現(xiàn)代碼例子,需要的朋友可以參考下
    2015-03-03
  • C#去除字符串中的反斜杠實(shí)例(推薦)

    C#去除字符串中的反斜杠實(shí)例(推薦)

    下面小編就為大家分享一篇C#去除字符串中的反斜杠實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • C#中DataGridView常用操作實(shí)例小結(jié)

    C#中DataGridView常用操作實(shí)例小結(jié)

    這篇文章主要介紹了C#中DataGridView常用操作,以實(shí)例形式總結(jié)了DataGridView綁定下拉列表、設(shè)置默認(rèn)值、判斷復(fù)選框是否選中等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09

最新評(píng)論