国产睡熟迷奷白丝护士系列精品,中文色字幕网站,免费h网站在线观看的,亚洲开心激情在线

      <sup id="hb9fh"></sup>
          1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

            手機(jī)站
            千鋒教育

            千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

            千鋒教育

            掃一掃進(jìn)入千鋒手機(jī)站

            領(lǐng)取全套視頻
            千鋒教育

            關(guān)注千鋒學(xué)習(xí)站小程序
            隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

            當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > Linux內(nèi)存管理

            Linux內(nèi)存管理

            來(lái)源:千鋒教育
            發(fā)布人:syq
            時(shí)間: 2022-10-27 10:57:40 1666839460

              一、物理內(nèi)存的組織形式:

              由于物理內(nèi)存是連續(xù)的,頁(yè)也是連續(xù)的,每個(gè)頁(yè)的大小一樣,從0開(kāi)始給每個(gè)頁(yè)編號(hào),每個(gè)頁(yè)用struct page表示,存放在一個(gè)大數(shù)組里。因此對(duì)于任何一個(gè)地址,只要除以頁(yè)的大小,就可以得到對(duì)應(yīng)頁(yè)的編號(hào),根據(jù)下標(biāo)就可以找到對(duì)應(yīng)的struct page結(jié)構(gòu),這種模型是最經(jīng)典的平坦內(nèi)存模型:

            Linux內(nèi)存管理

              所有的CPU總是通過(guò)總線(xiàn)去訪(fǎng)問(wèn)內(nèi)存,這是最經(jīng)典的內(nèi)存使用方法,它可以使用平坦內(nèi)存模型來(lái)管理內(nèi)存:

            1

              在這種模式下,所有的CPU都在總線(xiàn)的一側(cè),所有的內(nèi)存組成一大塊內(nèi)存在總線(xiàn)的另外一側(cè),CPU訪(fǎng)問(wèn)內(nèi)存都需要通過(guò)總線(xiàn)訪(fǎng)問(wèn),而且距離都是一樣的,這種模式稱(chēng)為SMP(Symmetric multiprocessing),即為對(duì)稱(chēng)多處理器。這種模式有一個(gè)顯著的缺點(diǎn),就是每個(gè)CPU訪(fǎng)問(wèn)內(nèi)存都需要通過(guò)總線(xiàn),那么總線(xiàn)就會(huì)成為瓶頸:

            2

              為了提高性能,有了一種更加高級(jí)的模式,NUMA(Non-uniform memory access),非一致內(nèi)存訪(fǎng)問(wèn)。這種模式下,內(nèi)存不是組成連續(xù)的一大塊,而是每個(gè)CPU都有自己的一塊內(nèi)存,CPU訪(fǎng)問(wèn)內(nèi)存不需要經(jīng)過(guò)總線(xiàn),所以速度上會(huì)更快,每個(gè)CPU和內(nèi)存組成一個(gè)NUMA節(jié)點(diǎn)。但是在本地內(nèi)存不足的情況下,每個(gè)CPU會(huì)去其他NUMA節(jié)點(diǎn)申請(qǐng)內(nèi)存,此時(shí)內(nèi)存的訪(fǎng)問(wèn)時(shí)間就比較長(zhǎng)

              這樣內(nèi)存被分為多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都分成一個(gè)一個(gè)的頁(yè)。由于頁(yè)是全局唯一定位的,所以每個(gè)頁(yè)都需要有一個(gè)全局唯一的頁(yè)號(hào)。但是由于物理內(nèi)存不再是連續(xù)的,所以頁(yè)號(hào)也不是連續(xù)的,于是內(nèi)存模型就變成了非連續(xù)內(nèi)存模型,管理起來(lái)就會(huì)比較復(fù)雜。

              二、節(jié)點(diǎn):

              下面解析當(dāng)前主流場(chǎng)景,NUMA方式。

              為了表示一個(gè)NUMA節(jié)點(diǎn),內(nèi)核定義了struct pglist_struct這樣一個(gè)結(jié)構(gòu)體,如下:

            3

              每個(gè)節(jié)點(diǎn)都有自己的ID:node_id

              node_mem_map是這個(gè)節(jié)點(diǎn)struct page數(shù)組,用于描述這個(gè)節(jié)點(diǎn)所有的頁(yè)

              node_start_pfn是這個(gè)節(jié)點(diǎn)的起始頁(yè)號(hào)

              node_spanned_pages是整個(gè)物理內(nèi)存包含的頁(yè)數(shù)目(包括空洞)

              node_present_pages是真正可用的物理頁(yè)數(shù)目

              例如:64M物理內(nèi)存隔著4M的空洞,然后再是另外的64M,換算成頁(yè)數(shù)目,分別是16K、1K、16K。那么node_spanned_pages就是33K,node_spanned_pages就是32K

              每個(gè)節(jié)點(diǎn)被分為一個(gè)一個(gè)的區(qū)域zone,存放在node_zones數(shù)組中,數(shù)組的大小為MAX_NR_ZONES,定義如下:

            4

              這里說(shuō)明以下,這些分區(qū)都是對(duì)物理內(nèi)存的說(shuō)明:

              ZONE_DMA:用作DMA的物理內(nèi)存

              ZONE_DMA32:對(duì)于64位CPU,還有這個(gè)DMA區(qū)域

              ZONE_NORMAL:就是直接映射區(qū)

              ZONE_MOVABLE:可移動(dòng)區(qū)域,通過(guò)將物理內(nèi)存劃分為可移動(dòng)分配區(qū)域和不可移動(dòng)分配區(qū)域來(lái)避免內(nèi)存碎片

              __MAX_NR_ZONES:內(nèi)存區(qū)域的數(shù)量

              內(nèi)核中有一個(gè)數(shù)組用來(lái)存放節(jié)點(diǎn):

            5

              三、區(qū)域:

              到這里,將內(nèi)存分為節(jié)點(diǎn),將節(jié)點(diǎn)分為區(qū)域,下面來(lái)看一看區(qū)域的定義

              區(qū)域是zone結(jié)構(gòu)體表示:

            6

              zone_start_pfn:表示這個(gè)屬于這個(gè)zone的第一個(gè)頁(yè)

              spanned_pages:注釋里有spanned_pages = zone_end_pfn - zone_start_pfn,表示spanned_pages就是結(jié)束頁(yè)面減去起始頁(yè)面的頁(yè)面數(shù),不管中間是否存在空洞

              present_pages:注釋里有spanned_pages - absent_pages(pages in holes),表示減去空洞后的頁(yè)面數(shù)

              managed_pages:注釋中有managed_pages = present_pages - reserved_pages,表示這個(gè)zone中被伙伴系統(tǒng)管理的所有的page數(shù)目

              per_cpu_pageset:用于區(qū)分冷熱頁(yè)。什么是冷熱頁(yè)?指的是一個(gè)頁(yè)是否被加載進(jìn)CPU的高速緩存中。

              四、頁(yè):

              在了解區(qū)域后,再來(lái)看組成物理內(nèi)存最基本的單位頁(yè),頁(yè)的數(shù)組結(jié)構(gòu)使用struct page表示。這個(gè)結(jié)構(gòu)體定義非常的復(fù)雜,因?yàn)橹С侄喾N使用模式,所以定義了許多union:

            7

              第一模式:

              要用就使用一整頁(yè)。這一整頁(yè)的內(nèi)存要么直接跟虛擬地址建立映射關(guān)系,這中稱(chēng)為匿名頁(yè)(Anonymous Page)。或者關(guān)聯(lián)一個(gè)文件,然后再跟虛擬地址建立映射

              如果某一頁(yè)使用此模式,那么union就使用以下的結(jié)構(gòu):

              struct address_space *mapping 就是用于內(nèi)存映射,如果是匿名頁(yè),最低位為1;如果是映射文件,最低位為0

              pgoff_t index 是映射區(qū)的偏移量

              atomic_t _mapcount 每個(gè)進(jìn)程都有自己的頁(yè)表,這個(gè)變量是指有多少個(gè)頁(yè)表映射到這個(gè)物理頁(yè)

              struct list_head lru 表示這一頁(yè)應(yīng)該在鏈表上,如果這一頁(yè)被換出,那么就應(yīng)該在換出頁(yè)的鏈表中

              compound相關(guān)的變量用于復(fù)合頁(yè),就是將物理上連續(xù)的兩個(gè)或者多個(gè)看成一個(gè)獨(dú)立的大頁(yè)

              第二種模式:

              僅需要分配一小塊內(nèi)存,并不需要一整頁(yè)。為了滿(mǎn)足這種需求,Linux系統(tǒng)采用了一種被稱(chēng)為slab allocator的技術(shù),用于分配slab中的一小塊內(nèi)存。它的基本工作原理是申請(qǐng)一整塊頁(yè),然后劃分成許多小塊的存儲(chǔ)池,用復(fù)雜的隊(duì)列來(lái)維護(hù)這些小塊的狀態(tài)(被分配了 / 被放回池子了 / 應(yīng)該被回收)

              slab對(duì)于隊(duì)列的維護(hù)過(guò)于復(fù)雜,后來(lái)出現(xiàn)了一種不使用隊(duì)列的分配器slub allocator,它保留的slab的用戶(hù)接口,可以把它看作是slab的另一種實(shí)現(xiàn)

              還有一種小塊內(nèi)存的分配器slob

              如果某一頁(yè)被切分為一小塊一小塊,那么union中就會(huì)使用以下結(jié)構(gòu):

              s_mem 是已經(jīng)分配了正在使用的slab的第一個(gè)對(duì)象

              freelist 是池子的空閑對(duì)象

              rcu_head 是需要釋放的列表

              五、頁(yè)的分配:

              前面講了物理內(nèi)存的組織,從NUMA節(jié)點(diǎn)到區(qū)域到頁(yè)再到小塊。接下倆看物理內(nèi)存的分配

              對(duì)于要分配比較大的內(nèi)存,例如分配頁(yè)級(jí)別的,可以使用伙伴系統(tǒng)(Buddy System)

              Linux內(nèi)存管理的頁(yè)大小為4K。把所有空閑的頁(yè)分組為11個(gè)頁(yè)塊鏈表,每個(gè)鏈表管理相應(yīng)大小的頁(yè)塊,有1、2、4、8、16、32、64、128、256、512、1024個(gè)連續(xù)頁(yè)的頁(yè)塊。最大可以申請(qǐng)1024個(gè)連續(xù)的頁(yè),對(duì)應(yīng)4M大小的連續(xù)內(nèi)存。每個(gè)頁(yè)塊第一頁(yè)的起始地址是該頁(yè)塊大小的整數(shù)倍:

            8

              在 struct zone 里面有以下的定義:

              struct free_area free_area[MAX_ORDER];

              MAX_ORDER表示2的指數(shù):

              #define MAX_ORDER 11

              當(dāng)申請(qǐng)的頁(yè)塊大小介于free_area中兩個(gè)頁(yè)塊大小之間時(shí),會(huì)選取更大的一個(gè)頁(yè)塊大小,或者如果對(duì)應(yīng)的大小沒(méi)有空閑的頁(yè)塊,那么也會(huì)分配一個(gè)更大的頁(yè)塊。在得到一個(gè)更大的頁(yè)塊后,會(huì)將其進(jìn)行拆分,然后將空閑的頁(yè)塊繼續(xù)插入到對(duì)應(yīng)頁(yè)塊大小的鏈表中

              例如申請(qǐng)一個(gè)128個(gè)頁(yè)的頁(yè)塊,如果沒(méi)有,那么就找256,然后一直如此,直到能夠找到。如果找到的是256個(gè)頁(yè)的頁(yè)塊。那么就會(huì)將其拆分為128和128個(gè)頁(yè)大小的頁(yè)塊,然后將一個(gè)空閑的頁(yè)塊添加到128對(duì)應(yīng)的頁(yè)塊鏈表中

              對(duì)于這些內(nèi)容,可以在 alloc_pages 函數(shù)中找到定義:

            9

              order:表示分配2的指數(shù)個(gè)頁(yè)的頁(yè)塊

              gfp:分配標(biāo)志,表示要分配那么區(qū)域的物理頁(yè)

              GFP_USER 表示分配一個(gè)頁(yè)映射到用戶(hù)虛擬地址空間,并且希望直接被內(nèi)核或者硬件訪(fǎng)問(wèn),主要用于一個(gè)用戶(hù)進(jìn)程希望通過(guò)內(nèi)存映射的方式,訪(fǎng)問(wèn)硬件緩存(如顯卡緩存)

              GFP_KERNEL 用于內(nèi)核中分配頁(yè),主要分配 ZONE_NORMAL 區(qū)域的內(nèi)存

              GFP_HIGHMEM 用于分配高端區(qū)域的物理內(nèi)存

              接下來(lái)調(diào)用 get_page_from_freelist,這是伙伴系統(tǒng)的核心。它會(huì)先循環(huán)查找對(duì)應(yīng)節(jié)點(diǎn)的zone,如果找不到,那么就看備用節(jié)點(diǎn)的zone:

            10

              每一個(gè)zone,都有伙伴系統(tǒng)維護(hù)的各種大小的隊(duì)列

              rmqueue 就是找到合適大小的隊(duì)列,然后將頁(yè)塊取下來(lái)

              最終會(huì)調(diào)用到 __rmqueue_smallest:

            11

              從指定的區(qū)域中,按照當(dāng)前指定的指數(shù)開(kāi)始查找,如果找不到,那么就到更大的指數(shù)查找。除了將頁(yè)塊從鏈表取下,還要將多余的頁(yè)面插入到合適的鏈表中,expand 就是完成這個(gè)工作:

            12

              六、總結(jié):

              如果有多個(gè)CPU,就會(huì)有多個(gè)NUMA節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)使用 struct pglist_data 表示,存放在一個(gè)數(shù)組中

              每個(gè)節(jié)點(diǎn)分為多個(gè)區(qū)域,每個(gè)區(qū)域使用 struct zone 表示,也存放在一個(gè)數(shù)組中

              每個(gè)區(qū)域分為多個(gè)頁(yè),空閑頁(yè)存放在 struct free_area 中,使用伙伴系統(tǒng)進(jìn)行管理和分配

              每一頁(yè)都是使用 struct page 表示:

            13

            tags:
            聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
            10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
            請(qǐng)您保持通訊暢通,專(zhuān)屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
            免費(fèi)領(lǐng)取
            今日已有369人領(lǐng)取成功
            劉同學(xué) 138****2860 剛剛成功領(lǐng)取
            王同學(xué) 131****2015 剛剛成功領(lǐng)取
            張同學(xué) 133****4652 剛剛成功領(lǐng)取
            李同學(xué) 135****8607 剛剛成功領(lǐng)取
            楊同學(xué) 132****5667 剛剛成功領(lǐng)取
            岳同學(xué) 134****6652 剛剛成功領(lǐng)取
            梁同學(xué) 157****2950 剛剛成功領(lǐng)取
            劉同學(xué) 189****1015 剛剛成功領(lǐng)取
            張同學(xué) 155****4678 剛剛成功領(lǐng)取
            鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
            董同學(xué) 138****2867 剛剛成功領(lǐng)取
            周同學(xué) 136****3602 剛剛成功領(lǐng)取
            相關(guān)推薦HOT
            為什么SpringBoot的 jar 可以直接運(yùn)行?

            一、JAR文件的結(jié)構(gòu)與執(zhí)行方式Spring Boot的JAR包是Java Archive的縮寫(xiě),它是一種壓縮文件格式,可以將Java項(xiàng)目的類(lèi)文件、資源文件以及依賴(lài)庫(kù)等...詳情>>

            2023-10-14 23:01:49
            站群服務(wù)器是什么?

            站群服務(wù)器的含義與用途站群服務(wù)器主要用于支持站群,即由一組相互鏈接的網(wǎng)站組成的群體。這些網(wǎng)站通常由同一組織或個(gè)人擁有,并且經(jīng)常會(huì)互相鏈...詳情>>

            2023-10-14 22:46:12
            自編碼器是什么?

            一、自編碼器原理自編碼器的設(shè)計(jì)靈感源于神經(jīng)科學(xué)中關(guān)于感知系統(tǒng)的認(rèn)知原理,它的核心思想是將輸入數(shù)據(jù)經(jīng)過(guò)編碼過(guò)程,形成一個(gè)隱藏層的特征表示...詳情>>

            2023-10-14 22:41:10
            什么是云網(wǎng)融合?

            一、云網(wǎng)融合的定義云網(wǎng)融合是指將云計(jì)算與網(wǎng)絡(luò)技術(shù)相結(jié)合,實(shí)現(xiàn)資源的共享、業(yè)務(wù)的協(xié)同,將網(wǎng)絡(luò)與云端服務(wù)深度融合,提供更靈活、高效、安全的...詳情>>

            2023-10-14 22:31:47
            什么是setnx、Redlock、Redisson?

            一、setnxsetnx是Redis中的一個(gè)命令,用于將鍵值對(duì)(key-value)設(shè)置到Redis數(shù)據(jù)庫(kù)中。其中,setnx表示”Set if Not Exists”,即當(dāng)...詳情>>

            2023-10-14 22:22:53