Linux虛擬記憶體 brk sbrk

2021-06-17 15:31:58 字數 2509 閱讀 4296

虛擬記憶體

問題:乙個程式不能訪問另外乙個程式的位址指向的空間.

理解:1.每個程式的開始位址0x80084000

2.程式中使用的位址不是物理,而是邏輯位址(虛擬記憶體).

邏輯位址僅僅是編號.編號使用int 4位元組整數表示.

每個程式提供了4g的訪問能力

問題:邏輯位址與實體地址關聯才有意義:過程稱為記憶體對映.

背景:虛擬記憶體的提出:禁止使用者直接訪問物理儲存裝置.

有助於系統的穩定.

結論:虛擬位址與物理位址對映的時候有乙個基本單位:

4k  1000 記憶體頁.

段錯誤:無效訪問.

合法訪問:比如malloc分配的空間之外的空間可以訪問,但訪問非法.

虛擬記憶體的分配.

棧:編譯器自動生成**維護

堆:位址是否對映,對映的空間是否被管理.

1.brk/sbrk記憶體對映函式

分配釋放記憶體:            

intbrk(void *end);//分配空間,釋放空間

void*sbrk(int size);//返回空間位址

應用:1.使用sbrk分配空間/size為正 分配空間 size為負 可釋放空間

2.使用sbrk得到沒有對映的虛擬位址.

3.使用brk分配空間

4.使用brk釋放空間

理解:sbrk(int  size)

sbrk與brk後台系統維護乙個指標.

指標預設是null.

呼叫sbrk,判定指標是否是0,是:得到大塊空閒空間的首位址初始化指標.同時把指標+size

否:返回指標,並且把指標位置+size

例子:linux下

**1:

#include

#include

void main()

int * p1=sbrk(0);     //得到大塊空閒空間的首位址初始化指標

int * p2=sbrk(4);     //分配4個位元組的空間先返回空閒空間的首位址,在將指標加4

printf(「%p\n」,p1);

printf(「%p\n」,p2);

printf(「%p\n」,p3);

執行結果:

0x9d9d000           sbrk(0)返回的空閒空間首位址

0x9d9d000        sbrk(0)返回的空間位址,並把位址+size(0x9d9d004)0x9d9d000-0x9d9d004為sbrk(4)分配的4個位元組的空間

0x9d9d004            再次呼叫sbrk(4),返回的指標為位址0x9d9d004,指標再次+size

0x9d9d004-0x9d9d008為這次呼叫sbrk分配的4個位元組的空間

**2:

#include

#include

void main()

int* p=sbrk(0);     //返回空閒空間的首位址,但系統並沒有給虛擬記憶體對映物理記憶體

*p=800;           //會出現段錯誤,無法訪問p指向的位址的空間

brk(p+1);          //brk(p+1) 是把p指標向後移了4個位元組,系統把虛擬記憶體對映到了//物理記憶體(映**乙個頁的物理記憶體4k),brk分配了4個位元組的//動態記憶體空間

*p=800;           //不會出現段錯誤

brk(p);            //brk(p)又把指標向回移了4個位元組,釋放了4個位元組的空間

*p=800;           //則不能再訪問p的空間

應用案例:

寫乙個程式查詢1-10000之間所有的素數.

並且存放到緩衝,然後列印.

緩衝的實現使用sbrk/brk

流程:迴圈

判定是否素數(isprimer)

是,分配空間存放

不是,繼續下步.

**:#include

#include

int isprimer(int a)

inti;

for(i=2;iif(a%i==0)

return 1;

else

return 0;

void main()

int i=2;

int *p=sbrk(0);

int *r;

r=p;

for(;i<1000;i++)

if(isprimer(i)==0)

brk(r+1);

*r=i;

r=sbrk(0);

r=p;

while(r!=sbrk(0))

printf(「%d\n」,*r);

r++brk(p); //free

brk/sbrk

異常處理

intbrk(void*)

void*sbrk(int);

如果成功.brk返回0  sbrk返回指標

失敗 brk返回-1  sbrk返回(void*)-1

Linux虛擬記憶體

linux採用虛擬段頁式儲存方式來管理記憶體,程式的基本邏輯儲存單元,也可以說是程式段。linux中有四個段,段,資料段,bss段,堆疊段。虛擬位址從低到高依次是 段,資料段,bss段,堆疊段。其中 段為程式本身 二進位制指令 資料段為 中初始化了的全域性變數和靜態變數,bss段為為初始化的全域性變...

Linux虛擬記憶體

一 虛擬記憶體 1 系統會為每個程序分4g的虛擬記憶體空間。32個0 32個1 位址範圍。2 使用者只能使用虛擬位址,無法直接使用物理記憶體。3 虛擬位址與物理記憶體進行對映才能使用,否則就會產生段錯誤。4 虛擬位址與物理記憶體的對映由作業系統動態維護。5 讓使用者使用虛擬位址一方面為了安全,另一方...

linux記憶體與虛擬記憶體

linux支援虛擬記憶體 記憶體 記憶體條 物理記憶體 實際存在 程式中的記憶體 虛擬記憶體 os對映出來的 直接對映 檔案對映 提速 檔案io操作 耗時長 記憶體操作 耗時短 mmap函式可以把檔案對映成虛擬記憶體,像操作記憶體一樣去操作檔案。mmap函式可以直接對映一塊虛擬記憶體。include...