複製鏈接
請複製以下鏈接發送給好友

VMA

(虛擬內存空間)

鎖定
VMA全稱為virtual memory area,指虛擬內存空間,又稱作線性區,表示一個線性區間。
中文名
虛擬內存空間
外文名
virtual memory area
稱    作
稱作線性區
描    述
表示一個線性區間

VMA含義簡介

從user process 角度來説明的話,VMA 是 user process 裏一段 virtual address space 區塊;virtual address space 是連續的記憶體空間,當然VMA也會是連續的空間。VMA 對 Linux 的主要好處是,可以使記憶體的使用更有效率,並且更容易管理 user process address space。
每個線性區描述符表示一個線性區間。進程所擁有的線性區從來不重疊,並且內核盡力把新分配的線性區與相鄰的現有線性區進行合併。如果兩個相鄰線性區的訪問權限匹配,就把它們合併在一起。為了存放進程的線性區,Linux既使用了鏈表(查找鏈表的時間複雜度是O(n)),也使用了紅黑樹(查找紅黑樹的時間複雜度是O(logn))。這兩種數據結構包含指向同一線性區描述符的指針,當插入或刪除一個線性區描述符時,內核通過紅黑樹搜索前後元素,並用搜索結果快速更新鏈表而不用掃描鏈表。
進程的vm_mm鏈接着屬於該進程的所有線性區間,如果CPU要訪問的地址(虛擬地址)不屬於任何一個線性區(即addrss不在任何一個線性區的vm_start~vm_end內,典型錯誤就是訪問了NULL指針指向的地址),就會產生段錯誤。

VMA數據結構

(參考自linux-2.6.11.11/include/linux/mm.h)如下:
structvm_area_struct{
structmm_struct*vm_mm;/*Theaddressspacewebelongto.*/
unsignedlongvm_start;/*Ourstartaddresswithinvm_mm.*/
unsignedlongvm_end;/*Thefirstbyteafterourendaddresswithinvm_mm.linkedlistofVMareaspertask,sortedbyaddress*/
structvm_area_struct*vm_next;

pgprot_tvm_page_prot;/*AccesspermissionsofthisVMA.*/
unsignedlongvm_flags;/*Flags,listedbelow.*/

structrb_nodevm_rb;
/*Forareaswithanaddressspaceandbackingstore,linkageintotheaddress_space->i_mmappriotree,orlinkagetothelistoflikevmashangingoffitsnode,orlinkageofvmaintheaddress_space->i_mmap_nonlinearlist.*/
union{
struct{
structlist_headlist;
void*parent;/*alignswithprio_tree_nodeparent*/
structvm_area_struct*head;}vm_set;

structraw_prio_tree_nodeprio_tree_node;
}shared;



/**Afile'sMAP_PRIVATEvmacanbeinbothi_mmaptreeandanon_vma*list,afteraCOWofoneofthefilepages.AMAP_SHAREDvma*canonlybeinthei_mmaptree.AnanonymousMAP_PRIVATE,stack*orbrkvma(withNULLfile)canonlybeinananon_vmalist.*/
structlist_headanon_vma_node;/*Serializedbyanon_vma->lock*/
structanon_vma*anon_vma;/*Serializedbypage_table_lock*/
/*Functionpointerstodealwiththisstruct.*/
structvm_operations_struct*vm_ops;
/*Informationaboutourbackingstore:*/
unsignedlongvm_pgoff;/*Offset(withinvm_file)inPAGE_SIZEunits,*not*PAGE_CACHE_SIZE*/
structfile*vm_file;/*Filewemapto(canbeNULL).*/
void*vm_private_data;/*wasvm_pte(sharedmem)*/
unsignedlongvm_truncate_count;/*truncate_countorrestart_addr*/

#ifndefCONFIG_MMUatomic_tvm_usage;/*refcount(VMAssharedif!MMU)*/
#endif
#ifdefCONFIG_NUMA
structmempolicy*vm_policy;/*NUMApolicyfortheVMA*/
#endif
};