小奋斗 - 轻松学习从此开始!
IT小奋斗群 QQ群:62017228

Linux虚拟内存相关知识总结

Linux 的虚拟内存管理有几个关键概念: 

1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; 

2、虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址; 

3、如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

Linux 虚拟地址空间如何分布? 

Linux 使用虚拟地址空间,大大增加了进程的寻址空间,

虚拟地址空间内由低地址到高地址分别为: 

1、只读段:该部分空间只能读,不可写;(包括:代码段、rodata 段(C常量字符串和#define定义的常量) ) 

2、数据段:保存全局变量、静态变量的空间; 

3、堆 :就是平时所说的动态内存, malloc/new 大部分都来源于此。其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。 

4、文件映射区域:如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。 

5、栈:用于维护函数调用的上下文空间,一般为 8M ,可通过 ulimit –s 查看。 

6、内核虚拟空间:用户代码不可见的内存区域,由内核管理(页表就存放在内核虚拟空间)。 

32 位系统有4G 的地址空间::

其中 0x08048000~0xbfffffff 是用户空间,0xc0000000~0xffffffff 是内核空间,包括内核代码和数据、与进程相关的数据结构(如页表、内核栈)等。另外,%esp 执行栈顶,往低地址方向变化;brk/sbrk 函数控制堆顶_edata往高地址方向变化。

64位系统结果怎样呢? 64 位系统是否拥有 2^64 的地址空间吗? 

事实上, 64 位系统的虚拟地址空间划分发生了改变: 

1、地址空间大小不是2^32,也不是2^64,

这可通过#cat  /proc/cpuinfo 来查看: 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

cache_alignment : 64

address sizes : 39 bits physical, 48 bits virtual

 

linux glibc malloc 是如何分配,回收内存的:

1、 malloc() 调用时,会冲系统堆上分配吗?  不一定。申请小块内存时,malloc先从自己的内存池中找,如果有的话直接用内存池种的。如果内存池中没有,则先从系统堆中申请(比如 sbrk)一大块128K多放入内存池,然后分配。 申请大块时,直接用mmap分配。

2、free()时,内存一定会归还给系统的堆上吗? 不一定。

 

关于内存泄漏:

狭义的内存泄漏就是代码中malloc/new分配了内存空间,该释放时却没有free/delete ,这样没有使用到的变量占用了进程的内存空间。

广义的内存泄漏:随着进程的运行,进程占用的内存空间不停增长。   这里使用malloc库,即使malloc,free这里使用正确,还是由可能出现内存泄漏,因为malloc内存池管理中会引入内部碎片,外部碎片,内存利用率也低。

我来评几句
登录后评论

已发表评论数(0)