关于内存管理的一点想法

框架:

首先,无论设备存储多大,我们平时说的几个T的硬盘,但是内存不大,比如4G/8G/16/,我以前的笔记本电脑是2G的,32位。

对于32位系统,满打满算就4G的空间,0x00000000-0xffffffff,无论32位还是64位,对于运行在上面的很多进程,都是有自己的虚拟内存的,说是虚拟内存,也就是说并不是真的给你这么多,用多少给多少。

代码段/数据段/BSS段/堆/栈是 对于进程上面的用户空间3G而言,进程上面当然还有内核空间1G,只不过是所有进程公用的。

内核空间的1G要映射真正的4G物理内存,这里面896M是直接映射,剩下的128M映射大部分物理内存,靠的是动态映射。vmalloc只是其一,还有两种,vmalloc线性内存是连续的,但是映射的物理内存就不一定了。(64位的就肯定不是这种寻址机制,靠的是家底丰厚)

这4G物理内存也有说道,DMA区16M,normal区880M ,这就是直接映射的896M的来源。

物理内存分配:

基本单位是页,一个4kb,外部碎片(连续分配/释放,但是分配是尽量连续的,这是原因),解决是伙伴分配法:相同大小的页组成链表,有大有小,丰简由人

内部碎片(一个页没有用完,浪费),slab算法,不按一页分。缓存池概念,搞个池子存除已经初始化的对象,释放是回到池子中来,而不是给到伙伴系统。

分为高速缓存(kmalloc和kfree)和专用高速缓存(kmem_cache_alloc和kmem_cache_free)。

kmalloc在驱动程序中用的最多,多用于分配小内存,连续,由slab分配器分配。vmalloc用于分配大内存,目标是物理内存,按页分,不一定连续。kmalloc可以通过配置flags配置为可睡眠或者不可睡眠,GFP_KERNEL可以睡眠 。GFP_ATOMIC不可以睡眠,适合用在中断处理函数里面。与GFP_ATOMIC相比,使用GFP_KERNEL的分配失败的情况要少得多

虚拟内存分配:

包含用户空间虚拟内存和内核空间虚拟内存。

malloc分配一大块内存池,然后在内存池中分割很多不同大小的内存块,谁要给谁,减小CPU开销

猜你喜欢

转载自blog.csdn.net/beibei_xiansen/article/details/110088124