内存分配是Linux比较复杂也是比较重要的部分,这个和ssd驱动很类似:物理地址和虚拟地址的映射关系。下面总结下最近看到的有关内存分配的内容和自己的理解;

1、一致内存访问和非一致内存访问



上图来自《深入linux设备驱动程序内核机制》

简单的说明下,UMA(一致内存访问 uniform memory access)可以很好的看到所有cpu访问内存的距离都是一样的(其实就是通过总线到内存的速度和距离都是一样的)所以就叫一致内存访问;

很显然右边的NUMA就是非一致内存访问,内存节点0是CPU0的本地内存(虽然其他CPU也可以访问,但是没有CPU0的速度高),所以这样各个CPU访问内存节点都会首先选择本地内存节点,然后再考虑其他内存节点;

2、物理内存和虚拟地址

上图来自《深入linux设备驱动程序内核机制》

首先大概的可以看出左边的mem_map数组中存放的是page结构体元素,中间的是实际的物理内存,右边的是虚拟的地址范围;

他们之间的关系大概是这样的,mem_map数组中的元素和物理内存页联系,page指针指向中间的物理内存中的某个物理页,这个关系是为了系统方便管理内存;

而物理内存页和右边的虚拟地址范围映射,这个是为了操作物理内存,一般右边的虚拟地址由cpu使用(软件上使用的也是虚拟地址,不过该地址最终还是CPU使用)。CPU和MMU之间使用的都是虚拟地址,出了MMU后就转换为实际的物理内存地址,一般有两个地方使用:1、总线上;2、物理内存(可以理解为内存条上);

这里类比下SSD驱动的原理:FTL数组中存放的是pba(lun、block、page、offset),而数组下标为lba,pba是SSD上的实际物理地址,lba则是上层软件使用的逻辑地址;他们通过FTL数组来映射,这样就可以通过修改数组中的pba来实现SSD像硬盘那样覆盖写等硬盘的特有性能;

回到内存分配上,从上面的图中应该可以看出物理内存分为三大区域:ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM;mem_map数组和物理内存页全部一一映射,也会形成三大区域;而在系统初始化期间,会把物理内存区域中ZONE_DMA和ZONE_NORMAL分别和右边的虚拟地址“物理页面直接映射区”(这个虚拟地址区域名称有点怪,其实就是内核地址的0~896M地址范围)建立线性映射,这样就会建立相应的页目录和页表;如果对右边这个虚拟地址范围分配有疑问的可以看看:http://blog.csdn.net/yuzhihui_no1/article/details/46982231,不过这些都是在32位的系统中的,在64位系统中可以说完全不一样,不过有这个概念会好点;

这时候,如果在内核内存ZONE_DMA和ZONE_NORMAL区域分配,则可以直接返回虚拟地址(0~896M)这个虚拟地址的界限不是固定的;如果需要在物理内存ZONE_HIGHMEM分配时,则要复杂些了;简单的步骤为:1、在物理内存ZONE_HIGHMEM中查找一个空闲页;2、在右边的虚拟地址中的动态映射区或固定映射区分配一个虚拟地址;3、建立页目录和页表,使物理页和虚拟地址映射起来;

3、物理页分配接口函数

    首先是:alloc_pages(gfp_mask, order)宏,(是不是很奇怪没有先写kmalloc、vmalloc,那是因为他们俩比较复杂,也比较重要,当然最主要的是他们不是分配物理页。后面要用很大的篇幅来分析他们俩);参数 gfp_mask是一个掩码参数,用来控制分配行为(哪个区域分配、是否阻塞分配等);order是表示分配2的order次方个物理页面;
alloc_pages(gfp_mask, order); 调用 alloc_pages_node(); 调用 __alloc_pages();说到底最后工作的还是__alloc_pages(),alloc_pages()和__alloc_pages()都可以分配来自ZONE_HIGHMEM区域的物理页,主要看gfp_mask指定的分配区域; 注意alloc_pages()是宏不是函数;
__get_free_pages(gfp_mask, order);这个分配函数首先是判断gfp_mask,如果指定为ZONE_HIGHMEM分配区域,则失败退出;否则,就调用alloc_pages()函数;由此看出__get_free_pages()函数只能分配ZONE_DMA和ZONE_NORMAL区域的物理页,也就是说不需要修改页表;

简单的分配物理页接口函数就这两个,其他的都是些变种,根据gfp_mask,和order来实现的变种函数;

注意:这是分配多个的连续的物理页的函数接口,kmalloc、vmalloc函数分配的不一定是整个页大小的内存;

转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/47284329

如果讲解的不正确,欢迎指正,谢谢!!

linux内核内存分配(一、基本概念)的更多相关文章

  1. linux内核内存分配(三、虚拟内存管理)

    在分析虚拟内存管理前要先看下linux内核内存的具体分配我開始就是困在这个地方.对内核内存的分类不是非常清晰.我摘录当中的一段: 内核内存地址 ============================ ...

  2. LINUX内核内存屏障

    =================                          LINUX内核内存屏障                          ================= By ...

  3. linux内核--内存管理(二)

    一.进程与内存     所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内 ...

  4. Linux内核-内存回收逻辑和算法(LRU)

    Linux内核内存回收逻辑和算法(LRU) LRU 链表 在 Linux 中,操作系统对 LRU 的实现主要是基于一对双向链表:active 链表和 inactive 链表,这两个链表是 Linux ...

  5. Linux内核内存管理算法Buddy和Slab: /proc/meminfo、/proc/buddyinfo、/proc/slabinfo

    slabtop cat /proc/slabinfo # name <active_objs> <num_objs> <objsize> <objpersla ...

  6. 模拟linux的内存分配与回收

    模拟linux的内存分配与回收 要求 通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码. 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣. (1)掌握内存分配FF,BF ...

  7. 【转】Linux内核中分配4M以上大内存的方法

    在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数,     "if (unlikely(order & ...

  8. linux环境内存分配原理 mallocinfo

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  9. linux内核内存管理(zone_dma zone_normal zone_highmem)

    Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...

随机推荐

  1. JAVA数据库连接的另一种实现及简单的数据插入及显示

    教材是JDK8的,家里也可以正规的测试JDK8, 但公司电脑是JDK6的,所以代码要相应的变动一下下,以适应老的TRY语句. Message.java package cc.openhome; imp ...

  2. 11gR2 集群(CRS/GRID)新功能—— SCAN(Single Client Access Name)

    https://blogs.oracle.com/database4cn/11gr2-crsgrid-scansingle-client-access-name

  3. 50套html站点模板,涵盖非常多行业,各种类型html站点,各种行业html站点模板下载

    50套html站点模板,涵盖非常多行业,各种类型html站点.各种行业html站点模板下载 所以模板都在共享文件中面QQ群 139639813 ,快下载吧.

  4. hdoj1051Wooden Sticks

     /*这道题目是先要排序的,依照长度或者重量排都能够. 当长度(重量)同样时就依照重量(长度)排, 从大到小或从小到大都能够! 这里我懂的.没有问题! 排序之后,问题就能够简化,(如果依照长度不等 ...

  5. 简陋版:基于python的自动化测试框架开发

    项目背景: XXXX银行项目采用的是B/S架构,主要是为了解决银行业务中的柜员.凭证.现金.账务等来自存款.贷款.会计模块的管理. 手工弊端: 1.项目业务复杂度高,回归测试工作量大2.单个接口功能比 ...

  6. Linux - 理不清的权限chmod与chown区别

    chmod是修改第一列内容的 ,chown是修改第3,4列内容的. [root@local ~]# chmod 777 -R add.sh [root@local ~]# chown jiqing:j ...

  7. 【NOIP 2011】 计算系数

    [题目链接] https://www.luogu.org/problemnew/show/P1313 [算法] 二项式定理 [代码] #include<bits/stdc++.h> usi ...

  8. 备份SQL SERVER 2005数据库

  9. shopping car 2.0

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2018/5/13 0013 10:20# @Author : Anthony.Waa# @ ...

  10. (转)Java进阶java int与Integer的区别

    Java进阶java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象,用一个引 ...