日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

內核空間 和用戶空間申請的內存最終和buddy怎么交互?以及在頁表映射上的區別?虛擬地址到物理地址,什么時候開始映射?

Buddy的問題

分配的力度太大 buddy算法把空閑頁面分成1,2,4頁,buddy算法會明確知道哪一頁內存空閑還是被占用?

4k,8k,16k

無論是在應用還是內核,都需要申請很小的內存。

從buddy要到的內存,會進行slab切割。

slab原理:

比如在內核中申請8字節的內存,buddy分配4K,分成很多個小的8個字節,每個都是一個object。

slab,slub,slob 是slab機制的三種不同實現算法。

linux 會針對一些常規的小的內存申請,數據結構,會做slab申請。

cat /proc/slabinfo 可以看到內核空間小塊內存的申請情況,也是slab分配的情況。

<num_objs>:每個slab一共可以分出多少個obj, <active_objs> :還可以分配多少個obj, < pagesperslab>:每個slab對應多少個pages, < objperslab>:每個slab可以分出多少個object, < objsize>:每個obj多大,

slab主要分為兩類:

一、常用數據結構像 nfsd_drc, UDPv6,TCPv6 ,這些經常申請和釋放的數據結構。比如,存在TCPv6的slab,之后申請 TCPv6 數據結構時,會通過這個slab來申請。

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

二、常規的小內存申請,做的slab。例如 kmalloc-32,kmalloc-64, kmalloc-96, kmalloc-128

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 


Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

注意,slab申請和分配的都是只針對內核空間,與用戶空間申請分配內存無關。用戶空間的malloc和free調用的是libc。

更多Linux內核視頻教程文檔資料免費領取后臺私信【內核大禮包】自行獲取。

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

slab和buddy的關系?
1、slab的內存來自于buddy。slab相當于二級管理器。
2、slab和buddy在算法上,級別是對等的。

兩者都是內存分配器,buddy是把內存條分成多個Zone來管理分配,slab是把從buddy拿到的內存,進行管理分配。

同理,malloc 和free也不找buddy拿內存。 malloc 和free不是系統調用,只是c庫中的函數。

mallopt

在C庫中有一個api是mallopt,可以控制一系列的選項。

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

M_TRIM_THRESHOLD:控制c庫把內存還給內核的閾值。
-1UL 代表最大的正整數。

此處代表應用程序把內存還給c庫后,c庫并不把內存還給內核。

<do your RT-thing>
程序在此處申請內存,都不需要再和內核交互了,此時程序的實時性比較高。

kmalloc vs. vmalloc/ioremap

內存空間: 內存+寄存器

register --> LDR/STR

所有內存空間的東西,CPU去訪問,都要通過虛擬地址。 CPU --> virt --> mmu --> phys

cpu請求虛擬地址,mmu根據cpu請求的虛擬地址,查頁表的物理地址。

buddy算法,管理這一頁的使用情況。

兩個虛擬地址可以映射到同一個物理地址。

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

頁表 -> 數組,任何一個虛擬地址,都可以用地址的高20位,作為頁表的行號去讀對應的頁表項。而第12位,是指頁面內偏移。(由于一頁是4K,2^12 足夠描述)

kmalloc 和 vmalloc 申請的內存,有什么區別? 答:申請之后,是否還要去改頁表。一般情況,kmalloc申請內存,不需要再去改頁表。同一張頁表,幾個虛擬地址可以同時映射到同一個物理地址。

寄存器,通過ioremap往vmalloc區域,進行映射。然后改進程的虛擬地址頁表。

總結:所有的頁,最底層都是用buddy算法進行管理,用虛擬地址找物理地址。理解內存分配和映射的區別,無論是lowmem還是highmem 都可以被vmalloc拿走,也可能被用戶拿走,只不過拿走之后,還要把虛擬地址往物理地址再映射一遍。但如果是被kmalloc拿走,一般指低端內存,就不需要再改進程的頁表。因為這部分低端內存,已經做好了虛實映射。

	cat /proc/vmallocinfo |grep ioremap

可以看到寄存器中的哪個區域,被映射到哪個虛擬地址。

vmalloc區域主要用來,vmalloc申請的內存從這里找虛擬地址 和 寄存器的ioremap映射。

Linux內存分配的lazy行為

Linux總是以最lazy的方式,給應用程序分配內存。

Linux內核:虛擬地址到物理地址,是什么時候開始映射

 

malloc100M內存成功時,其實并沒有真實拿到。只有當100M內存中的任何一頁,被寫一次的時候,才成功。vss:虛擬地址空間。 rss:常駐內存空間malloc 100M內存成功時,Linux把100M內存全部以只讀的形式,映射到一個全部清0的頁面。

當應用程序寫100M中每一頁任意字節時,會發出page fault。 linux 內核收到缺頁中斷后,從硬件寄存器中讀取到,包括缺頁中斷發生的原因和虛擬地址。Linux從內存條申請一頁內存,執行cow,把頁面重新拷貝到新申請的頁表,再把進程頁表中的虛擬地址,指向一個新的物理地址,權限也被改成R+W。

調用brk 把8k變成 16k。

針對應用程序的堆、代碼、棧、等,會使用lazy分配機制,只有當寫內存頁時,才會真實請求內存分配頁表。但,當內核使用kmalloc申請內存時,就真實地分配相應的內存,不使用lazy機制。

內存OOM

當真實去寫內存時,應用程序并不能拿到真實的內存時。Linux啟動OOM,linux在運行時,會對每一個進程進行out-of-memory打分。大部分主要基于,耗費的內存。耗費的內存越多,打分越高。

cat /proc/<pid>/oom_score
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    int max = -1;
    int mb = 0;
    char *buffer;
    int i;
#define SIZE 2000
    unsigned int *p = malloc(1024 * 1024 * SIZE);
    printf("malloc buffer: %pn", p);
    for (i = 0; i < 1024 * 1024 * (SIZE/sizeof(int)); i++) {
        p[i] = 123;
        if ((i & 0xFFFFF) == 0) {
            printf("%dMB writtenn", i >> 18);
            usleep(100000);
        }
    }
    pause();
    return 0;
}

定條件:

總內存1G
1、swapoff -a 關掉swap交換
2、echo 1 >
/proc/sys/vm/overcommit_memory
3、內核不去評估系統還有多少空閑內存

Linux進行OOM打分,主要是看耗費內存情況,此外還會參考用戶權限,比如root權限,打分會減少30分。

還有OOM打分因子:/proc/pid/oom_score_adj (加減)和 /proc/pid/oom_adj (乘除)。

總結:

1、slab的作用,針對在內核空間小內存分配,和常用數據結構的申請。
2、同樣的二次分配器,在用戶空間是C庫。malloc和free的時候,內存不一定從buddy分配和還給buddy。
3、kmalloc,vmalloc 和malloc的區別

  • kmalloc:申請內存,一般在低端內存區。申請到時,內存已經映射過了,不需要再去改進程的頁表。所以,申請到的物理頁是連續的。
  • vmalloc:申請內存,申請到就拿到內存,并且已經修改了進程頁表的虛擬地址到物理地址的映射。vmalloc()申請的內存并不保證物理地址的連續。
  • 用戶空間的malloc:申請內存,申請到并沒有拿到,寫的時候才去拿到。拿到之后,才去改頁表。申請成功,頁表只讀,只有到寫時,發生page fault,才去buddy拿內存。
  • kmalloc和vmalloc針對內核空間,malloc針對用戶空間。這些內存,可以來自任何一個Zone。
  • 無論是kmalloc,vmalloc還是用戶空間的malloc,都可以使用內存條的不同Zone,無論是highmem zone、lowmem zone 和 DMA zone。

4、如果在從buddy拿不到內存時,會觸發Linux對所有進程進行OOM打分。當Linux出現內存耗盡,就kill一個oom score 最高的是那個進程。oom_score,可以根據 oom_adj (-17~25)。

Android/ target=_blank class=infotextkey>安卓的程序,不停地調整前臺和后臺進程oom_score,當被切換到后臺時,oom_score會被調整得比較大。以保證前臺的進程不容易因為oom而kill掉。

分享到:
標簽:映射
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定