日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
了解Linux進(jìn)程內(nèi)存區(qū)域的基礎(chǔ)知識(shí)(linux進(jìn)程內(nèi)存區(qū)域)

Linux是一個(gè)開(kāi)源的操作系統(tǒng),在計(jì)算機(jī)領(lǐng)域得到了廣泛的應(yīng)用。其中一個(gè)重要的特點(diǎn)就是 Linux 的進(jìn)程管理,進(jìn)程是 Linux 系統(tǒng)架構(gòu)的基礎(chǔ)之一。當(dāng)進(jìn)程在 Linux 系統(tǒng)中運(yùn)行時(shí),每個(gè)進(jìn)程將被分配一個(gè)獨(dú)立的內(nèi)存空間。這個(gè)內(nèi)存空間是進(jìn)程獨(dú)有的,用于存儲(chǔ)進(jìn)程的變量、數(shù)據(jù)、程序代碼等。了解 Linux 進(jìn)程的內(nèi)存區(qū)域,對(duì)于有效地管理進(jìn)程、傳遞數(shù)據(jù)和調(diào)試程序都是至關(guān)重要的。

Linux 進(jìn)程的內(nèi)存區(qū)域可以大致分為五個(gè)部分:代碼區(qū)、數(shù)據(jù)區(qū)、BSS、堆區(qū)和棧區(qū)。在下面的文章中,我們將深入了解每個(gè)內(nèi)存區(qū)域及其功能。

1. 代碼區(qū)(Text Segment)

代碼區(qū)在 Linux 進(jìn)程中主要用于存儲(chǔ)程序代碼。代碼區(qū)通常被稱為文本段(Text Segment)。文本段存放的是可執(zhí)行的程序或函數(shù)的二進(jìn)制代碼。 這些代碼在程序調(diào)用執(zhí)行時(shí)被載入到內(nèi)存中,并且不能寫(xiě)入。當(dāng)程序被執(zhí)行時(shí),代碼區(qū)是只讀的,但是該區(qū)域的代碼允許修改文本屬性。代碼區(qū)是一個(gè)唯一的區(qū)域,并且多個(gè)進(jìn)程可以共享同一個(gè)代碼區(qū)。

2. 數(shù)據(jù)區(qū)(Data Segment)

數(shù)據(jù)區(qū)在 Linux 進(jìn)程中通常用于存儲(chǔ)已經(jīng)初始化的全局變量。數(shù)據(jù)區(qū)讀寫(xiě)可行,包括程序中事先賦予初始值的全局變量和靜態(tài)變量。 數(shù)據(jù)區(qū)的位置通常是在代碼區(qū)之后,它們?cè)趦?nèi)存中存儲(chǔ)的順序是以它們初始化的順序排列的。

3. BSS塊(Block Started by Symbol)

BSS 區(qū)域在 Linux 進(jìn)程中通常被用于存儲(chǔ)未初始化的全局變量。BSS 區(qū)域是一個(gè)只讀的區(qū)域,保存的是全局變量的符號(hào)(變量名)和大小,而不是真正的數(shù)據(jù)內(nèi)容。由于 BSS 區(qū)域能夠存儲(chǔ)大量的未初始化數(shù)據(jù),因此它可以減少可執(zhí)行文件的大小。 BSS 塊通常位于數(shù)據(jù)段后面的內(nèi)存空間。

4. 堆區(qū)(Heap Segment)

堆區(qū)在 Linux 進(jìn)程中用于動(dòng)態(tài)分配內(nèi)存。在程序運(yùn)行的時(shí)候,可以通過(guò)動(dòng)態(tài)分配內(nèi)存的方式創(chuàng)建對(duì)象,并可在運(yùn)行期動(dòng)態(tài)調(diào)整這些對(duì)象的大小。堆區(qū)是一個(gè)存在于數(shù)據(jù)區(qū)和棧區(qū)之間的連續(xù)內(nèi)存段。堆是在運(yùn)行期間動(dòng)態(tài)分配的內(nèi)存空間,使用 malloc 或 new 等命令在程序中申請(qǐng)使用。堆區(qū)域的大小并不固定,也不會(huì)在程序結(jié)束時(shí)被自動(dòng)回收。這就需要程序員在用完堆內(nèi)存后及時(shí)釋放它。

5. 棧區(qū)(Stack Segment)

棧是 Linux 進(jìn)程中一塊存儲(chǔ)在用戶空間中的一段連續(xù)內(nèi)存區(qū)域。棧通常被分配在進(jìn)程的虛擬地址空間頂部。入棧和出棧的過(guò)程遵循先進(jìn)后出(Last-in-first-out,LIFO)原則。棧區(qū)深度通常是固定的,是由操作系統(tǒng)在創(chuàng)建新進(jìn)程時(shí)預(yù)先設(shè)置好的。同一進(jìn)程中的不同線程會(huì)共享同一棧,因?yàn)闂^(qū)位置已經(jīng)確定。棧的主要作用是存儲(chǔ)臨時(shí)變量、參數(shù)、返回地址和函數(shù)調(diào)用等信息。棧中的內(nèi)存是動(dòng)態(tài)分配的,由系統(tǒng)負(fù)責(zé)管理。

對(duì)于 Linux 開(kāi)發(fā)人員來(lái)說(shuō),了解進(jìn)程的內(nèi)存區(qū)域是至關(guān)重要的。通過(guò)熟悉不同的內(nèi)存區(qū)域,可以使開(kāi)發(fā)人員更好地管理進(jìn)程、傳遞變量、調(diào)試程序以及預(yù)防內(nèi)存泄漏。掌握這些內(nèi)存區(qū)域的基本知識(shí),可以提高代碼開(kāi)發(fā)和維護(hù)的效率,也是成為一名優(yōu)秀 Linux 開(kāi)發(fā)人員的必備技能。

相關(guān)問(wèn)題拓展閱讀:

  • linux中使用了什么內(nèi)存管理方法,為什么
  • linux共享內(nèi)存存在于進(jìn)程空間的什么位置

linux中使用了什么內(nèi)存管理方法,為什么

“事實(shí)勝于雄辯”,我們用一個(gè)小例子(原形取自《User-Level Memory Management》)來(lái)展示上面所講的各種內(nèi)存區(qū)的差別與位置。

#include

 

#include

 

#include

int bss_var;

int data_var0=1;

int main(int argc,char **argv)

 

{

 

   printf(“below are addresses of types of process’s mem\n”);

 

   printf(“Text location:\n”);

 

   printf(“\tAddress of main(Code Segment):%p\n”,main);

 

   printf(“____________________________\n”);

 

   int stack_var0=2;

 

   printf(“Stack Location:\n”);

 

   printf(“\tInitial end of stack:%p\n”,&stack_var0);

 

   int stack_var1=3;

 

   printf(“\tnew end of stack:%p\n”,&stack_var1);

 

   printf(“____________________________\n”);

 

   printf(“Data Location:\n”);

 

   printf(“\tAddress of data_var(Data Segment):%p\n”,&data_var0);

 

   static int data_var1=4;

 

   printf(“\tNew end of data_var(Data Segment):%p\n”,&data_var1);

 

  printf(“____________________________\n”);

 

   printf(“BSS Location:\n”);

 

   printf(“\tAddress of bss_var:%p\n”,&bss_var);

 

  printf(“____________________________\n”);

 

   char *b = rk((ptrdiff_t)0);

 扒掘

  printf(“Heap Location:\n”);

 

  printf(“\tInitial end of heap:%p\n”,b);

 

  brk(b+4);

 

   b=rk((ptrdiff_t)0);

 

   printf(“\tNew end of heap:%p\n”,b);

 

 return 0;

 

 }

它的結(jié)果如下:

below are addresses of types of process’s mem

Text location:

 

   Address of main(Code Segment):0x

 

____________________________

 

Stack Location:

 塌山

   Initial end of stack:0xbffffab4

 

   new end of stack:0xbffffab0

 

____________________________

 

Data Location:

 

   Address of data_var(Data Segment):0x

 

   New end of data_var(Data Segment):0x804975c

 

____________________________

 

BSS Location:

 

   Address of bss_var:0x

 

____________________________

 

Heap Location:

 

   Initial end of heap:0x

 

   New end of heap:0x804986c

利用size命令也可以看到程序的各段大小,比如執(zhí)行size example會(huì)得到

text    data bss dec   hex filename

example

但這些數(shù)據(jù)是程序編譯的靜態(tài)統(tǒng)計(jì),而上面顯示的是進(jìn)程運(yùn)行時(shí)的動(dòng)態(tài)值,但兩者是對(duì)應(yīng)的。

 

通過(guò)前面的例子,我們對(duì)進(jìn)程使用的邏輯內(nèi)存分布已先睹為快。這部分我們就繼續(xù)進(jìn)入操作系統(tǒng)內(nèi)核看看,進(jìn)程對(duì)內(nèi)存具體是如何進(jìn)行分配和管理的。

從用戶向內(nèi)核看,所使用的內(nèi)存表象形團(tuán)此中式會(huì)依次經(jīng)歷“邏輯地址”——“線性地址”——“物理地址”幾種形式(關(guān)于幾種地址的解釋在前面已經(jīng)講述了)。邏輯地址經(jīng)段機(jī)制轉(zhuǎn)化成線性地址;線性地址又經(jīng)過(guò)頁(yè)機(jī)制轉(zhuǎn)化為物理地址。(但是我們要知道Linux系統(tǒng)雖然保留了段機(jī)制,但是將所有程序的段地址都定死為0-4G,所以雖然邏輯地址和線性地址是兩種不同的地址空間,但在Linux中邏輯地址就等于線性地址,它們的值是一樣的)。沿著這條線索,我們所研究的主要問(wèn)題也就集中在下面幾個(gè)問(wèn)題。

進(jìn)程空間地址如何管理?

進(jìn)程地址如何映射到物理內(nèi)存?

物理內(nèi)存如何被管理?

以及由上述問(wèn)題引發(fā)的一些子問(wèn)題。如系統(tǒng)虛擬地址分布;內(nèi)存分配接口;連續(xù)內(nèi)存分配與非連續(xù)內(nèi)存分配等。

進(jìn)程內(nèi)存空間

Linux操作系統(tǒng)采用虛擬內(nèi)存管理技術(shù),使得每個(gè)進(jìn)程都有各自互不干涉的進(jìn)程地址空間。該空間是塊大小為4G的線性虛擬空間,用戶所看到和接觸到的都是該虛擬地址,無(wú)法看到實(shí)際的物理內(nèi)存地址。利用這種虛擬地址不但能起到保護(hù)操作系統(tǒng)的效果(用戶不能直接訪問(wèn)物理內(nèi)存),而且更重要的是,用戶程序可使用比實(shí)際物理內(nèi)存更大的地址空間(具體的原因請(qǐng)看硬件基礎(chǔ)部分)。

在討論進(jìn)程空間細(xì)節(jié)前,這里先要澄清下面幾個(gè)問(wèn)題:

l之一、4G的進(jìn)程地址空間被人為的分為兩個(gè)部分——用戶空間與內(nèi)核空間。用戶空間從0到3G(0xC),內(nèi)核空間占據(jù)3G到4G。用戶進(jìn)程通常情況下只能訪問(wèn)用戶空間的虛擬地址,不能訪問(wèn)內(nèi)核空間虛擬地址。只有用戶進(jìn)程進(jìn)行系統(tǒng)調(diào)用(代表用戶進(jìn)程在內(nèi)核態(tài)執(zhí)行)等時(shí)刻可以訪問(wèn)到內(nèi)核空間。

l第二、用戶空間對(duì)應(yīng)進(jìn)程,所以每當(dāng)進(jìn)程切換,用戶空間就會(huì)跟著變化;而內(nèi)核空間是由內(nèi)核負(fù)責(zé)映射,它并不會(huì)跟著進(jìn)程改變,是固定的。內(nèi)核空間地址有自己對(duì)應(yīng)的頁(yè)表(init_mm.pgd),用戶進(jìn)程各自有不同的頁(yè)表。

l第三、每個(gè)進(jìn)程的用戶空間都是完全獨(dú)立、互不相干的。不信的話,你可以把上面的程序同時(shí)運(yùn)行10次(當(dāng)然為了同時(shí)運(yùn)行,讓它們?cè)诜祷厍耙煌?00秒吧),你會(huì)看到10個(gè)進(jìn)程占用的線性地址一模一樣。

進(jìn)程內(nèi)存管理

進(jìn)程內(nèi)存管理的對(duì)象是進(jìn)程線性地址空間上的內(nèi)存鏡像,這些內(nèi)存鏡像其實(shí)就是進(jìn)程使用的虛擬內(nèi)存區(qū)域(memory region)。進(jìn)程虛擬空間是個(gè)32或64位的“平坦”(獨(dú)立的連續(xù)區(qū)間)地址空間(空間的具體大小取決于體系結(jié)構(gòu))。要統(tǒng)一管理這么大的平坦空間可絕非易事,為了方便管理,虛擬空間被劃分為許多大小可變的(但必須是4096的倍數(shù))內(nèi)存區(qū)域,這些區(qū)域在進(jìn)程線性地址中像停車位一樣有序排列。這些區(qū)域的劃分原則是“將訪問(wèn)屬性一致的地址空間存放在一起”,所謂訪問(wèn)屬性在這里無(wú)非指的是“可讀、可寫(xiě)、可執(zhí)行等”。

如果你要查看某個(gè)進(jìn)程占用的內(nèi)存區(qū)域,可以使用命令cat /proc//maps獲得(pid是進(jìn)程號(hào),你可以運(yùn)行上面我們給出的例子——./example &;pid便會(huì)打印到屏幕),你可以發(fā)現(xiàn)很多類似于下面的數(shù)字信息。

由于程序example使用了動(dòng)態(tài)庫(kù),所以除了example本身使用的的內(nèi)存區(qū)域外,還會(huì)包含那些動(dòng)態(tài)庫(kù)使用的內(nèi)存區(qū)域(區(qū)域順序是:代碼段、數(shù)據(jù)段、bss段)。

我們下面只抽出和example有關(guān)的信息,除了前兩行代表的代碼段和數(shù)據(jù)段外,最后一行是進(jìn)程使用的??臻g。

49000 r-xp:/home/mm/src/example

4a000 rw-p:/home/mm/src/example

……………

bfffe000 – crwxp ffff000 00:00 0

——

每行數(shù)據(jù)格式如下:

(內(nèi)存區(qū)域)開(kāi)始-結(jié)束 訪問(wèn)權(quán)限  偏移  主設(shè)備號(hào):次設(shè)備號(hào) i節(jié)點(diǎn)  文件。

注意,你一定會(huì)發(fā)現(xiàn)進(jìn)程空間只包含三個(gè)內(nèi)存區(qū)域,似乎沒(méi)有上面所提到的堆、bss等,其實(shí)并非如此,程序內(nèi)存段和進(jìn)程地址空間中的內(nèi)存區(qū)域是種模糊對(duì)應(yīng),也就是說(shuō),堆、bss、數(shù)據(jù)段(初始化過(guò)的)都在進(jìn)程空間中由數(shù)據(jù)段內(nèi)存區(qū)域表示。

在Linux內(nèi)核中對(duì)應(yīng)進(jìn)程內(nèi)存區(qū)域的數(shù)據(jù)結(jié)構(gòu)是: vm_area_struct, 內(nèi)核將每個(gè)內(nèi)存區(qū)域作為一個(gè)單獨(dú)的內(nèi)存對(duì)象管理,相應(yīng)的操作也都一致。采用面向?qū)ο蠓椒ㄊ筕MA結(jié)構(gòu)體可以代表多種類型的內(nèi)存區(qū)域--比如內(nèi)存映射文件或進(jìn)程的用戶空間棧等,對(duì)這些區(qū)域的操作也都不盡相同。

vm_area_strcut結(jié)構(gòu)比較復(fù)雜,關(guān)于它的詳細(xì)結(jié)構(gòu)請(qǐng)參閱相關(guān)資料。我們這里只對(duì)它的組織方法做一點(diǎn)補(bǔ)充說(shuō)明。vm_area_struct是描述進(jìn)程地址空間的基本管理單元,對(duì)于一個(gè)進(jìn)程來(lái)說(shuō)往往需要多個(gè)內(nèi)存區(qū)域來(lái)描述它的虛擬空間,如何關(guān)聯(lián)這些不同的內(nèi)存區(qū)域呢?大家可能都會(huì)想到使用鏈表,的確vm_area_struct結(jié)構(gòu)確實(shí)是以鏈表形式鏈接,不過(guò)為了方便查找,內(nèi)核又以紅黑樹(shù)(以前的內(nèi)核使用平衡樹(shù))的形式組織內(nèi)存區(qū)域,以便降低搜索耗時(shí)。并存的兩種組織形式,并非冗余:鏈表用于需要遍歷全部節(jié)點(diǎn)的時(shí)候用,而紅黑樹(shù)適用于在地址空間中定位特定內(nèi)存區(qū)域的時(shí)候。內(nèi)核為了內(nèi)存區(qū)域上的各種不同操作都能獲得高性能,所以同時(shí)使用了這兩種數(shù)據(jù)結(jié)構(gòu)。

下圖反映了進(jìn)程地址空間的管理模型:

請(qǐng)點(diǎn)擊輸入圖片描述

進(jìn)程的地址空間對(duì)應(yīng)的描述結(jié)構(gòu)是“內(nèi)存描述符結(jié)構(gòu)”,它表示進(jìn)程的全部地址空間,——包含了和進(jìn)程地址空間有關(guān)的全部信息,其中當(dāng)然包含進(jìn)程的內(nèi)存區(qū)域。

進(jìn)程內(nèi)存的分配與回收

創(chuàng)建進(jìn)程fork()、程序載入execve()、映射文件mmap()、動(dòng)態(tài)內(nèi)存分配malloc()/brk()等進(jìn)程相關(guān)操作都需要分配內(nèi)存給進(jìn)程。不過(guò)這時(shí)進(jìn)程申請(qǐng)和獲得的還不是實(shí)際內(nèi)存,而是虛擬內(nèi)存,準(zhǔn)確的說(shuō)是“內(nèi)存區(qū)域”。進(jìn)程對(duì)內(nèi)存區(qū)域的分配最終都會(huì)歸結(jié)到do_mmap()函數(shù)上來(lái)(brk調(diào)用被單獨(dú)以系統(tǒng)調(diào)用實(shí)現(xiàn),不用do_mmap()),

內(nèi)核使用do_mmap()函數(shù)創(chuàng)建一個(gè)新的線性地址區(qū)間。但是說(shuō)該函數(shù)創(chuàng)建了一個(gè)新VMA并不非常準(zhǔn)確,因?yàn)槿绻麆?chuàng)建的地址區(qū)間和一個(gè)已經(jīng)存在的地址區(qū)間相鄰,并且它們具有相同的訪問(wèn)權(quán)限的話,那么兩個(gè)區(qū)間將合并為一個(gè)。如果不能合并,那么就確實(shí)需要?jiǎng)?chuàng)建一個(gè)新的VMA了。但無(wú)論哪種情況, do_mmap()函數(shù)都會(huì)將一個(gè)地址區(qū)間加入到進(jìn)程的地址空間中--無(wú)論是擴(kuò)展已存在的內(nèi)存區(qū)域還是創(chuàng)建一個(gè)新的區(qū)域。

同樣,釋放一個(gè)內(nèi)存區(qū)域應(yīng)使用函數(shù)do_ummap(),它會(huì)銷毀對(duì)應(yīng)的內(nèi)存區(qū)域。

如何由虛變實(shí)!

從上面已經(jīng)看到進(jìn)程所能直接操作的地址都為虛擬地址。當(dāng)進(jìn)程需要內(nèi)存時(shí),從內(nèi)核獲得的僅僅是虛擬的內(nèi)存區(qū)域,而不是實(shí)際的物理地址,進(jìn)程并沒(méi)有獲得物理內(nèi)存(物理頁(yè)面——頁(yè)的概念請(qǐng)大家參考硬件基礎(chǔ)一章),獲得的僅僅是對(duì)一個(gè)新的線性地址區(qū)間的使用權(quán)。實(shí)際的物理內(nèi)存只有當(dāng)進(jìn)程真的去訪問(wèn)新獲取的虛擬地址時(shí),才會(huì)由“請(qǐng)求頁(yè)機(jī)制”產(chǎn)生“缺頁(yè)”異常,從而進(jìn)入分配實(shí)際頁(yè)面的例程。

該異常是虛擬內(nèi)存機(jī)制賴以存在的基本保證——它會(huì)告訴內(nèi)核去真正為進(jìn)程分配物理頁(yè),并建立對(duì)應(yīng)的頁(yè)表,這之后虛擬地址才實(shí)實(shí)在在地映射到了系統(tǒng)的物理內(nèi)存上。(當(dāng)然,如果頁(yè)被換出到磁盤(pán),也會(huì)產(chǎn)生缺頁(yè)異常,不過(guò)這時(shí)不用再建立頁(yè)表了)

這種請(qǐng)求頁(yè)機(jī)制把頁(yè)面的分配推遲到不能再推遲為止,并不急于把所有的事情都一次做完(這種思想有點(diǎn)像設(shè)計(jì)模式中的代理模式(proxy))。之所以能這么做是利用了內(nèi)存訪問(wèn)的“局部性原理”,請(qǐng)求頁(yè)帶來(lái)的好處是節(jié)約了空閑內(nèi)存,提高了系統(tǒng)的吞吐率。要想更清楚地了解請(qǐng)求頁(yè)機(jī)制,可以看看《深入理解linux內(nèi)核》一書(shū)。

這里我們需要說(shuō)明在內(nèi)存區(qū)域結(jié)構(gòu)上的nopage操作。當(dāng)訪問(wèn)的進(jìn)程虛擬內(nèi)存并未真正分配頁(yè)面時(shí),該操作便被調(diào)用來(lái)分配實(shí)際的物理頁(yè),并為該頁(yè)建立頁(yè)表項(xiàng)。在最后的例子中我們會(huì)演示如何使用該方法。

系統(tǒng)物理內(nèi)存管理 

雖然應(yīng)用程序操作的對(duì)象是映射到物理內(nèi)存之上的虛擬內(nèi)存,但是處理器直接操作的卻是物理內(nèi)存。所以當(dāng)應(yīng)用程序訪問(wèn)一個(gè)虛擬地址時(shí),首先必須將虛擬地址轉(zhuǎn)化成物理地址,然后處理器才能解析地址訪問(wèn)請(qǐng)求。地址的轉(zhuǎn)換工作需要通過(guò)查詢頁(yè)表才能完成,概括地講,地址轉(zhuǎn)換需要將虛擬地址分段,使每段虛地址都作為一個(gè)索引指向頁(yè)表,而頁(yè)表項(xiàng)則指向下一級(jí)別的頁(yè)表或者指向最終的物理頁(yè)面。

每個(gè)進(jìn)程都有自己的頁(yè)表。進(jìn)程描述符的pgd域指向的就是進(jìn)程的頁(yè)全局目錄。下面我們借用《linux設(shè)備驅(qū)動(dòng)程序》中的一幅圖大致看看進(jìn)程地址空間到物理頁(yè)之間的轉(zhuǎn)換關(guān)系。

上面的過(guò)程說(shuō)起來(lái)簡(jiǎn)單,做起來(lái)難呀。因?yàn)樵谔摂M地址映射到頁(yè)之前必須先分配物理頁(yè)——也就是說(shuō)必須先從內(nèi)核中獲取空閑頁(yè),并建立頁(yè)表。下面我們介紹一下內(nèi)核管理物理內(nèi)存的機(jī)制。

物理內(nèi)存管理(頁(yè)管理)

Linux內(nèi)核管理物理內(nèi)存是通過(guò)分頁(yè)機(jī)制實(shí)現(xiàn)的,它將整個(gè)內(nèi)存劃分成無(wú)數(shù)個(gè)4k(在i386體系結(jié)構(gòu)中)大小的頁(yè),從而分配和回收內(nèi)存的基本單位便是內(nèi)存頁(yè)了。利用分頁(yè)管理有助于靈活分配內(nèi)存地址,因?yàn)榉峙鋾r(shí)不必要求必須有大塊的連續(xù)內(nèi)存,系統(tǒng)可以東一頁(yè)、西一頁(yè)的湊出所需要的內(nèi)存供進(jìn)程使用。雖然如此,但是實(shí)際上系統(tǒng)使用內(nèi)存時(shí)還是傾向于分配連續(xù)的內(nèi)存塊,因?yàn)榉峙溥B續(xù)內(nèi)存時(shí),頁(yè)表不需要更改,因此能降低TLB的刷新率(頻繁刷新會(huì)在很大程度上降低訪問(wèn)速度)。

鑒于上述需求,內(nèi)核分配物理頁(yè)面時(shí)為了盡量減少不連續(xù)情況,采用了“伙伴”關(guān)系來(lái)管理空閑頁(yè)面?;锇殛P(guān)系分配算法大家應(yīng)該不陌生——幾乎所有操作系統(tǒng)方面的書(shū)都會(huì)提到,我們不去詳細(xì)說(shuō)它了,如果不明白可以參看有關(guān)資料。這里只需要大家明白Linux中空閑頁(yè)面的組織和管理利用了伙伴關(guān)系,因此空閑頁(yè)面分配時(shí)也需要遵循伙伴關(guān)系,最小單位只能是2的冪倍頁(yè)面大小。內(nèi)核中分配空閑頁(yè)面的基本函數(shù)是get_free_page/get_free_pages,它們或是分配單頁(yè)或是分配指定的頁(yè)面(2、4、8…512頁(yè))。

注意:get_free_page是在內(nèi)核中分配內(nèi)存,不同于malloc在用戶空間中分配,malloc利用堆動(dòng)態(tài)分配,實(shí)際上是調(diào)用brk()系統(tǒng)調(diào)用,該調(diào)用的作用是擴(kuò)大或縮小進(jìn)程堆空間(它會(huì)修改進(jìn)程的brk域)。如果現(xiàn)有的內(nèi)存區(qū)域不夠容納堆空間,則會(huì)以頁(yè)面大小的倍數(shù)為單位,擴(kuò)張或收縮對(duì)應(yīng)的內(nèi)存區(qū)域,但brk值并非以頁(yè)面大小為倍數(shù)修改,而是按實(shí)際請(qǐng)求修改。因此Malloc在用戶空間分配內(nèi)存可以以字節(jié)為單位分配,但內(nèi)核在內(nèi)部仍然會(huì)是以頁(yè)為單位分配的。

另外,需要提及的是,物理頁(yè)在系統(tǒng)中由頁(yè)結(jié)構(gòu)struct page描述,系統(tǒng)中所有的頁(yè)面都存儲(chǔ)在數(shù)組mem_map中,可以通過(guò)該數(shù)組找到系統(tǒng)中的每一頁(yè)(空閑或非空閑)。而其中的空閑頁(yè)面則可由上述提到的以伙伴關(guān)系組織的空閑頁(yè)鏈表(free_area)來(lái)索引。

內(nèi)核內(nèi)存使用

Slab

所謂尺有所長(zhǎng),寸有所短。以頁(yè)為最小單位分配內(nèi)存對(duì)于內(nèi)核管理系統(tǒng)中的物理內(nèi)存來(lái)說(shuō)的確比較方便,但內(nèi)核自身最常使用的內(nèi)存卻往往是很?。ㄟh(yuǎn)遠(yuǎn)小于一頁(yè))的內(nèi)存塊——比如存放文件描述符、進(jìn)程描述符、虛擬內(nèi)存區(qū)域描述符等行為所需的內(nèi)存都不足一頁(yè)。這些用來(lái)存放描述符的內(nèi)存相比頁(yè)面而言,就好比是面包屑與面包。一個(gè)整頁(yè)中可以聚集多個(gè)這些小塊內(nèi)存;而且這些小塊內(nèi)存塊也和面包屑一樣頻繁地生成/銷毀。

為了滿足內(nèi)核對(duì)這種小內(nèi)存塊的需要,Linux系統(tǒng)采用了一種被稱為slab分配器的技術(shù)。Slab分配器的實(shí)現(xiàn)相當(dāng)復(fù)雜,但原理不難,其核心思想就是“存儲(chǔ)池”的運(yùn)用。內(nèi)存片段(小塊內(nèi)存)被看作對(duì)象,當(dāng)被使用完后,并不直接釋放而是被緩存到“存儲(chǔ)池”里,留做下次使用,這無(wú)疑避免了頻繁創(chuàng)建與銷毀對(duì)象所帶來(lái)的額外負(fù)載。

Slab技術(shù)不但避免了內(nèi)存內(nèi)部分片(下文將解釋)帶來(lái)的不便(引入Slab分配器的主要目的是為了減少對(duì)伙伴系統(tǒng)分配算法的調(diào)用次數(shù)——頻繁分配和回收必然會(huì)導(dǎo)致內(nèi)存碎片——難以找到大塊連續(xù)的可用內(nèi)存),而且可以很好地利用硬件緩存提高訪問(wèn)速度。

Slab并非是脫離伙伴關(guān)系而獨(dú)立存在的一種內(nèi)存分配方式,slab仍然是建立在頁(yè)面基礎(chǔ)之上,換句話說(shuō),Slab將頁(yè)面(來(lái)自于伙伴關(guān)系管理的空閑頁(yè)面鏈表)撕碎成眾多小內(nèi)存塊以供分配,slab中的對(duì)象分配和銷毀使用kmem_cache_alloc與kmem_cache_free。

Kmalloc

Slab分配器不僅僅只用來(lái)存放內(nèi)核專用的結(jié)構(gòu)體,它還被用來(lái)處理內(nèi)核對(duì)小塊內(nèi)存的請(qǐng)求。當(dāng)然鑒于Slab分配器的特點(diǎn),一般來(lái)說(shuō)內(nèi)核程序中對(duì)小于一頁(yè)的小塊內(nèi)存的請(qǐng)求才通過(guò)Slab分配器提供的接口Kmalloc來(lái)完成(雖然它可分配32 到131072字節(jié)的內(nèi)存)。從內(nèi)核內(nèi)存分配的角度來(lái)講,kmalloc可被看成是get_free_page(s)的一個(gè)有效補(bǔ)充,內(nèi)存分配粒度更靈活了。

有興趣的話,可以到/proc/slabinfo中找到內(nèi)核執(zhí)行現(xiàn)場(chǎng)使用的各種slab信息統(tǒng)計(jì),其中你會(huì)看到系統(tǒng)中所有slab的使用信息。從信息中可以看到系統(tǒng)中除了專用結(jié)構(gòu)體使用的slab外,還存在大量為Kmalloc而準(zhǔn)備的Slab(其中有些為dma準(zhǔn)備的)。

內(nèi)核非連續(xù)內(nèi)存分配(Vmalloc)

伙伴關(guān)系也好、slab技術(shù)也好,從內(nèi)存管理理論角度而言目的基本是一致的,它們都是為了防止“分片”,不過(guò)分片又分為外部分片和內(nèi)部分片之說(shuō),所謂內(nèi)部分片是說(shuō)系統(tǒng)為了滿足一小段內(nèi)存區(qū)(連續(xù))的需要,不得不分配了一大區(qū)域連續(xù)內(nèi)存給它,從而造成了空間浪費(fèi);外部分片是指系統(tǒng)雖有足夠的內(nèi)存,但卻是分散的碎片,無(wú)法滿足對(duì)大塊“連續(xù)內(nèi)存”的需求。無(wú)論何種分片都是系統(tǒng)有效利用內(nèi)存的障礙。slab分配器使得一個(gè)頁(yè)面內(nèi)包含的眾多小塊內(nèi)存可獨(dú)立被分配使用,避免了內(nèi)部分片,節(jié)約了空閑內(nèi)存?;锇殛P(guān)系把內(nèi)存塊按大小分組管理,一定程度上減輕了外部分片的危害,因?yàn)轫?yè)框分配不在盲目,而是按照大小依次有序進(jìn)行,不過(guò)伙伴關(guān)系只是減輕了外部分片,但并未徹底消除。你自己比劃一下多次分配頁(yè)面后,空閑內(nèi)存的剩余情況吧。

所以避免外部分片的最終思路還是落到了如何利用不連續(xù)的內(nèi)存塊組合成“看起來(lái)很大的內(nèi)存塊”——這里的情況很類似于用戶空間分配虛擬內(nèi)存,內(nèi)存邏輯上連續(xù),其實(shí)映射到并不一定連續(xù)的物理內(nèi)存上。Linux內(nèi)核借用了這個(gè)技術(shù),允許內(nèi)核程序在內(nèi)核地址空間中分配虛擬地址,同樣也利用頁(yè)表(內(nèi)核頁(yè)表)將虛擬地址映射到分散的內(nèi)存頁(yè)上。以此完美地解決了內(nèi)核內(nèi)存使用中的外部分片問(wèn)題。內(nèi)核提供vmalloc函數(shù)分配內(nèi)核虛擬內(nèi)存,該函數(shù)不同于kmalloc,它可以分配較Kmalloc大得多的內(nèi)存空間(可遠(yuǎn)大于128K,但必須是頁(yè)大小的倍數(shù)),但相比Kmalloc來(lái)說(shuō),Vmalloc需要對(duì)內(nèi)核虛擬地址進(jìn)行重映射,必須更新內(nèi)核頁(yè)表,因此分配效率上要低一些(用空間換時(shí)間)

與用戶進(jìn)程相似,內(nèi)核也有一個(gè)名為init_mm的mm_strcut結(jié)構(gòu)來(lái)描述內(nèi)核地址空間,其中頁(yè)表項(xiàng)pdg=swapper_pg_dir包含了系統(tǒng)內(nèi)核空間(3G-4G)的映射關(guān)系。因此vmalloc分配內(nèi)核虛擬地址必須更新內(nèi)核頁(yè)表,而kmalloc或get_free_page由于分配的連續(xù)內(nèi)存,所以不需要更新內(nèi)核頁(yè)表。

vmalloc分配的內(nèi)核虛擬內(nèi)存與kmalloc/get_free_page分配的內(nèi)核虛擬內(nèi)存位于不同的區(qū)間,不會(huì)重疊。因?yàn)閮?nèi)核虛擬空間被分區(qū)管理,各司其職。進(jìn)程空間地址分布從0到3G(其實(shí)是到PAGE_OFFSET,在0x86中它等于0xC),從3G到vmalloc_start這段地址是物理內(nèi)存映射區(qū)域(該區(qū)域中包含了內(nèi)核鏡像、物理頁(yè)面表mem_map等等)比如我使用的系統(tǒng)內(nèi)存是64M(可以用free看到),那么(3G——3G+64M)這片內(nèi)存就應(yīng)該映射到物理內(nèi)存,而vmalloc_start位置應(yīng)在3G+64M附近(說(shuō)”附近”因?yàn)槭窃谖锢韮?nèi)存映射區(qū)與vmalloc_start期間還會(huì)存在一個(gè)8M大小的gap來(lái)防止躍界),vmalloc_end的位置接近4G(說(shuō)”接近”是因?yàn)樽詈笪恢孟到y(tǒng)會(huì)保留一片128k大小的區(qū)域用于專用頁(yè)面映射,還有可能會(huì)有高端內(nèi)存映射區(qū),這些都是細(xì)節(jié),這里我們不做糾纏)。 

請(qǐng)點(diǎn)擊輸入圖片描述

上圖是內(nèi)存分布的模糊輪廓

由get_free_page或Kmalloc函數(shù)所分配的連續(xù)內(nèi)存都陷于物理映射區(qū)域,所以它們返回的內(nèi)核虛擬地址和實(shí)際物理地址僅僅是相差一個(gè)偏移量(PAGE_OFFSET),你可以很方便的將其轉(zhuǎn)化為物理內(nèi)存地址,同時(shí)內(nèi)核也提供了virt_to_phys()函數(shù)將內(nèi)核虛擬空間中的物理映射區(qū)地址轉(zhuǎn)化為物理地址。要知道,物理內(nèi)存映射區(qū)中的地址與內(nèi)核頁(yè)表是有序?qū)?yīng)的,系統(tǒng)中的每個(gè)物理頁(yè)面都可以找到它對(duì)應(yīng)的內(nèi)核虛擬地址(在物理內(nèi)存映射區(qū)中的)。

而vmalloc分配的地址則限于vmalloc_start與vmalloc_end之間。每一塊vmalloc分配的內(nèi)核虛擬內(nèi)存都對(duì)應(yīng)一個(gè)vm_struct結(jié)構(gòu)體(可別和vm_area_struct搞混,那可是進(jìn)程虛擬內(nèi)存區(qū)域的結(jié)構(gòu)),不同的內(nèi)核虛擬地址被4k大小的空閑區(qū)間隔,以防止越界——見(jiàn)下圖)。與進(jìn)程虛擬地址的特性一樣,這些虛擬地址與物理內(nèi)存沒(méi)有簡(jiǎn)單的位移關(guān)系,必須通過(guò)內(nèi)核頁(yè)表才可轉(zhuǎn)換為物理地址或物理頁(yè)。它們有可能尚未被映射,在發(fā)生缺頁(yè)時(shí)才真正分配物理頁(yè)面。

這里給出一個(gè)小程序幫助大家認(rèn)清上面幾種分配函數(shù)所對(duì)應(yīng)的區(qū)域。

#include

#include

#include

unsigned char *pagemem;

unsigned char *kmallocmem;

unsigned char *vmallocmem;

int init_module(void)

{

pagemem = get_free_page(0);

printk(“pagemem=%s”,pagemem);

kmallocmem = kmalloc(100,0);

printk(“kmallocmem=%s”,kmallocmem);

vmallocmem = vmalloc();

printk(“vmallocmem=%s”,vmallocmem);

}

void cleanup_module(void)

{

free_page(pagemem);

kfree(kmallocmem);

vfree(vmallocmem);

}

實(shí)例

內(nèi)存映射(mmap)是Linux操作系統(tǒng)的一個(gè)很大特色,它可以將系統(tǒng)內(nèi)存映射到一個(gè)文件(設(shè)備)上,以便可以通過(guò)訪問(wèn)文件內(nèi)容來(lái)達(dá)到訪問(wèn)內(nèi)存的目的。這樣做的更大好處是提高了內(nèi)存訪問(wèn)速度,并且可以利用文件系統(tǒng)的接口編程(設(shè)備在Linux中作為特殊文件處理)訪問(wèn)內(nèi)存,降低了開(kāi)發(fā)難度。許多設(shè)備驅(qū)動(dòng)程序便是利用內(nèi)存映射功能將用戶空間的一段地址關(guān)聯(lián)到設(shè)備內(nèi)存上,無(wú)論何時(shí),只要內(nèi)存在分配的地址范圍內(nèi)進(jìn)行讀寫(xiě),實(shí)際上就是對(duì)設(shè)備內(nèi)存的訪問(wèn)。同時(shí)對(duì)設(shè)備文件的訪問(wèn)也等同于對(duì)內(nèi)存區(qū)域的訪問(wèn),也就是說(shuō),通過(guò)文件操作接口可以訪問(wèn)內(nèi)存。Linux中的X服務(wù)器就是一個(gè)利用內(nèi)存映射達(dá)到直接高速訪問(wèn)視頻卡內(nèi)存的例子。

熟悉文件操作的朋友一定會(huì)知道file_operations結(jié)構(gòu)中有mmap方法,在用戶執(zhí)行mmap系統(tǒng)調(diào)用時(shí),便會(huì)調(diào)用該方法來(lái)通過(guò)文件訪問(wèn)內(nèi)存——不過(guò)在調(diào)用文件系統(tǒng)mmap方法前,內(nèi)核還需要處理分配內(nèi)存區(qū)域(vma_struct)、建立頁(yè)表等工作。對(duì)于具體映射細(xì)節(jié)不作介紹了,需要強(qiáng)調(diào)的是,建立頁(yè)表可以采用remap_page_range方法一次建立起所有映射區(qū)的頁(yè)表,或利用vma_struct的nopage方法在缺頁(yè)時(shí)現(xiàn)場(chǎng)一頁(yè)一頁(yè)的建立頁(yè)表。之一種方法相比第二種方法簡(jiǎn)單方便、速度快, 但是靈活性不高。一次調(diào)用所有頁(yè)表便定型了,不適用于那些需要現(xiàn)場(chǎng)建立頁(yè)表的場(chǎng)合——比如映射區(qū)需要擴(kuò)展或下面我們例子中的情況。

我們這里的實(shí)例希望利用內(nèi)存映射,將系統(tǒng)內(nèi)核中的一部分虛擬內(nèi)存映射到用戶空間,以供應(yīng)用程序讀取——你可利用它進(jìn)行內(nèi)核空間到用戶空間的大規(guī)模信息傳輸。因此我們將試圖寫(xiě)一個(gè)虛擬字符設(shè)備驅(qū)動(dòng)程序,通過(guò)它將系統(tǒng)內(nèi)核空間映射到用戶空間——將內(nèi)核虛擬內(nèi)存映射到用戶虛擬地址。從上一節(jié)已經(jīng)看到Linux內(nèi)核空間中包含兩種虛擬續(xù)但非物理連續(xù)的vmalloc分配的內(nèi)存虛擬地址。我們的例子程序?qū)⒀菔景裿malloc分配的內(nèi)核虛擬地址映射到用戶地址空間的全過(guò)程。

程序里主要應(yīng)解決兩個(gè)問(wèn)題:

之一是如何將vmalloc分配的內(nèi)核虛擬內(nèi)存正確地轉(zhuǎn)化成物理地址?

因?yàn)閮?nèi)存映射先要獲得被映射的物理地址,然后才能將其映射到要求的用戶虛擬地址上。我們已經(jīng)看到內(nèi)核物理內(nèi)存映射區(qū)域中的地址可以被內(nèi)核函數(shù)virt_to_phys轉(zhuǎn)換成實(shí)際的物理內(nèi)存地址,但對(duì)于vmalloc分配的內(nèi)核虛擬地址無(wú)法直接轉(zhuǎn)化成物理地址,所以我們必須對(duì)這部分虛擬內(nèi)存格外“照顧”——先將其轉(zhuǎn)化成內(nèi)核物理內(nèi)存映射區(qū)域中的地址,然后在用virt_to_phys變?yōu)槲锢淼刂贰?/p>

轉(zhuǎn)化工作需要進(jìn)行如下步驟:

找到vmalloc虛擬內(nèi)存對(duì)應(yīng)的頁(yè)表,并尋找到對(duì)應(yīng)的頁(yè)表項(xiàng)。

獲取頁(yè)表項(xiàng)對(duì)應(yīng)的頁(yè)面指針

通過(guò)頁(yè)面得到對(duì)應(yīng)的內(nèi)核物理內(nèi)存映射區(qū)域地址。

如下圖所示:

第二是當(dāng)訪問(wèn)vmalloc分配區(qū)時(shí),如果發(fā)現(xiàn)虛擬內(nèi)存尚未被映射到物理頁(yè),則需要處理“缺頁(yè)異?!?。因此需要我們實(shí)現(xiàn)內(nèi)存區(qū)域中的nopaga操作,以能返回被映射的物理頁(yè)面指針,在我們的實(shí)例中就是返回上面過(guò)程中的內(nèi)核物理內(nèi)存映射區(qū)域中的地址。由于vmalloc分配的虛擬地址與物理地址的對(duì)應(yīng)關(guān)系并非分配時(shí)就可確定,必須在缺頁(yè)現(xiàn)場(chǎng)建立頁(yè)表,因此這里不能使用remap_page_range方法,只能用vma的nopage方法一頁(yè)一頁(yè)的建立。

程序組成

map_driver.c,它是以模塊形式加載的虛擬字符驅(qū)動(dòng)程序。該驅(qū)動(dòng)負(fù)責(zé)將一定長(zhǎng)的內(nèi)核虛擬地址(vmalloc分配的)映射到設(shè)備文件上。其中主要的函數(shù)有——vaddress_to_kaddress()負(fù)責(zé)對(duì)vmalloc分配的地址進(jìn)行頁(yè)表解析,以找到對(duì)應(yīng)的內(nèi)核物理映射地址(kmalloc分配的地址);map_nopage()負(fù)責(zé)在進(jìn)程訪問(wèn)一個(gè)當(dāng)前并不存在的VMA頁(yè)時(shí),尋找該地址對(duì)應(yīng)的物理頁(yè),并返回該頁(yè)的指針。

test.c 它利用上述驅(qū)動(dòng)模塊對(duì)應(yīng)的設(shè)備文件在用戶空間讀取讀取內(nèi)核內(nèi)存。結(jié)果可以看到內(nèi)核虛擬地址的內(nèi)容(ok!),被顯示在了屏幕上。

執(zhí)行步驟

編譯map_driver.c為map_driver.o模塊,具體參數(shù)見(jiàn)Makefile

加載模塊 :inod map_driver.o

生成對(duì)應(yīng)的設(shè)備文件

1 在/proc/devices下找到map_driver對(duì)應(yīng)的設(shè)備命和設(shè)備號(hào):grep mapdrv /proc/devices

2 建立設(shè)備文件mknod  mapfile c(在我的系統(tǒng)里設(shè)備號(hào)為254)

linux共享內(nèi)存存在于進(jìn)程空間的什么位置

共享內(nèi)存方式:從物理譽(yù)純內(nèi)存里面拿出來(lái)一部分作為多個(gè)進(jìn)程共享。   共享內(nèi)存是進(jìn)程間共享數(shù)據(jù)的一種最快的方法,一個(gè)進(jìn)程向共享內(nèi)存區(qū)域?qū)懭霐?shù)據(jù),共享這個(gè)內(nèi)存的所有進(jìn)程都可以立即看到其中內(nèi)容。   共享內(nèi)存實(shí)現(xiàn)步驟:   一、創(chuàng)建共享內(nèi)存,使用shmget函數(shù)。   二、映射共享內(nèi)存,將這段創(chuàng)建的共享內(nèi)存映射到具體的進(jìn)程空間去,使用shmat函數(shù)。   創(chuàng)建共享內(nèi)存shmget:   intshmget(key_t key, size_t size, int shm)   功能:得到一個(gè)共享內(nèi)存標(biāo)識(shí)符或創(chuàng)建一個(gè)共享內(nèi)存對(duì)象并返回共享內(nèi)存標(biāo)識(shí)符。   key: 0(IPC_PRIVATE)會(huì)建立共享內(nèi)存對(duì)象   size:大于0的整數(shù),新建共享內(nèi)存的大小,以字節(jié)為單位。只獲取共享內(nèi)存時(shí),指定為0.   shm:   0表示取共享內(nèi)存標(biāo)識(shí)符,如不存在則函數(shù)會(huì)報(bào)錯(cuò);   IPC_CREAT,如果內(nèi)核中不存在鍵值與key相等的共享內(nèi)存時(shí),則創(chuàng)賣鍵建一個(gè)共享內(nèi)存;如果存在這樣的共享內(nèi)存則返回共享內(nèi)存的標(biāo)識(shí)符;   IPC_CREATIPC_EXCL: 如果內(nèi)核中不存在鍵值與key相等的共享內(nèi)存,則新建一個(gè)消息隊(duì)列;如果存在這樣的共享慶配咐內(nèi)存則報(bào)錯(cuò);   函數(shù)返回值:成功則返回內(nèi)存的標(biāo)識(shí)符;出錯(cuò)則返回-1,錯(cuò)誤原因存在于error中   映射共享內(nèi)存到調(diào)用進(jìn)程的地址空間shmat:   void*shmat(int shmid, const void *shmaddr, int shm)   msqid:共享內(nèi)存標(biāo)識(shí)符   shmaddr:指定共享內(nèi)存出現(xiàn)在進(jìn)程內(nèi)存地址的什么位置,直接指定為NULL讓內(nèi)核自己決定一個(gè)合適的地址位置。   shm: SHM_RDON 只讀模式,其他為讀寫(xiě)模式   函數(shù)返回值:成功則返回附加好的共享內(nèi)存地址;出錯(cuò)返回-1,錯(cuò)誤原因存在于error中   斷開(kāi)共享內(nèi)存連接shmdt:   intshmdt(const void *shmaddr)   功能:傳入shmaddr,連接共享的內(nèi)存起始地址;斷開(kāi)成功則返回0,出錯(cuò)則返回-1,錯(cuò)誤原因存在于error中。   父子進(jìn)程間通訊實(shí)例:   #include   #include   #include   #include   #include   #include   int main(int argc, char **argv){   if(argc); // 拷貝共享數(shù)據(jù)到共享內(nèi)存   wait(NULL); //等待子進(jìn)程結(jié)束   exit(0);   }   else{   sleep(2); //等待父進(jìn)程寫(xiě)入數(shù)據(jù)   char*c_shmaddr;   c_shmaddr= shmat(shmid,NULL,0); // 映射到子進(jìn)程之中一個(gè)地址,具體由kernel 指配   printf(“theshare data is: %sn”, c_shmaddr); //子進(jìn)程輸出共享的數(shù)據(jù)   exit(0);   }   }linux進(jìn)程內(nèi)存區(qū)域的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux進(jìn)程內(nèi)存區(qū)域,了解Linux進(jìn)程內(nèi)存區(qū)域的基礎(chǔ)知識(shí),linux中使用了什么內(nèi)存管理方法,為什么,linux共享內(nèi)存存在于進(jìn)程空間的什么位置的信息別忘了在本站進(jìn)行查找喔。

香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開(kāi)通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。


分享題目:了解Linux進(jìn)程內(nèi)存區(qū)域的基礎(chǔ)知識(shí)(linux進(jìn)程內(nèi)存區(qū)域)
網(wǎng)站路徑:http://www.5511xx.com/article/dhgospj.html