当前位置: 首页 > news >正文

我是做废品回收,最近有个变宝网主动联系我说是再生资源网站的,可信吗?做专业搜索引擎优化

我是做废品回收,最近有个变宝网主动联系我说是再生资源网站的,可信吗?,做专业搜索引擎优化,网站开发iso9001,上海装修公司排名统帅第一部分 内存区(zone)内核用page结构表示所有的物理页.由于2个硬件缺陷问题导致分为3种类型的内存区.2个缺陷是1.一些硬件只能使用<16M的内存做DMA2.一些硬件的物理地址范围超过内核的虚拟地址范围3种类型内存区是(以物理内存大于896M为例,看完全文会明白为何这个是依赖于实…

第一部分 内存区(zone)

内核用page结构表示所有的物理页.

由于2个硬件缺陷问题导致分为3种类型的内存区.

2个缺陷是

1.一些硬件只能使用<16M的内存做DMA

2.一些硬件的物理地址范围超过内核的虚拟地址范围

3种类型内存区是(以物理内存大于896M为例,看完全文会明白为何这个是依赖于实际物理内存)

1.ZONE_DMA 0..16M

2.ZONE_NORMAL 16M..896M

3.ZONE_HIGHMEM >896M

ZONE_DMA和ZONE_NORMAL也称为低端内存

ZONE_HIGHMEM即传说中的高端内存

第二部分申请函数

内核申请内存的函数有3个

1.alloc_pages()返回的是page的指针,故支持高端内存.

2.__get_free_pages() 返回的是线性地址,故只用于低端内存.

3.kmalloc()以字节为单位,内部也是调用了__get_free_pages(),

故也只支持低端内存.注意的是可能分配的内存比请求地多,

因为它是用的slab实现的.

分配器标志有3类:行为/区/类型修饰符.

1.行为描述符,比如__GFP_WAIT标识可以睡眠.(GFP就是get free page的缩写)

2.区描述符,

__GFP_DMA标志标识仅从ZONE_DMA区中申请.

__GFP_HIGHMEM标志标识从ZONE_HIGHMEM(优先)或ZONE_NORMAL中申请.

不指定标志表示从ZONE_NORMAL或ZONE_DMA中申请.

对于__GFP_HIGHMEM标志,其实只能用于alloc_pages(),因为仅它支持高端内存.

3.类型是前2个的组合.

kmalloc()中使用的GFP_KERNEL,可以睡眠,只从低端内存中申请.

故只能用在进程上下文中.

而kmalloc()中使用的GFP_ATOMIC,不能睡眠,只从低端申请.

在不能睡眠时(中断/软中断/tasklet),只能用此标志.

可见kmalloc()只从低端申请.

GFP_DMA标志,表示只能从ZONE_DMA中申请,用于设备驱动程序中.

附:

GFP_ATOMIC的含义

The allocation is high priority and must not sleep.

This is the flag to use in interrupt handlers,

in bottom halves, while holding a spinlock, and in other situations where you cannot sleep

GFP_KERNEL的含义

This is a normal allocation and might block.

This is the flag to use in process context code when it is safe to sleep.

The kernel will do whatever it has to in order to obtain the memory requested by the caller.

This flag should be your first choice.

第三部分 高端内存

使用高端内存的2个途径

1.进程中调用alloc_pages(GFP_HIGHUSER)为用户空间分配内存.

2.进程上下文中,故可能会睡眠,常调vmalloc(),最终还是调用alloc_pages(),故

常用高端内存.

3.而在内核中,因为它的睡眠性极少用vmalloc(),但是当装载新模块需要申请大内存时会用到.

高端内存的映射有3种形式

1.永久,使用主内核页表的一页页表.

调用kmap完成映射.永久映射的个数是有限的.故会睡眠(睡前设置为不可中断的sleep状态等待),

因此kmap()只能用在进程上下文中.

2.临时,不会睡眠,故可以用在中断上下文中, 但是数量很少.

是一组保留的映射,被申请用作新建的临时映射.

kmap_atomic()建立临时映射,

映射时会禁止本cpu的中断,因为每个映射对于本cpu都是唯一的,如果切换会错误地覆盖.

而释放临时映射是空操作,因为本来就是在直接覆盖.

3.非连续

vmalloc()有3种非连续类型:

VM_ALLOC物理内存和线性地址同时申请,注意此时指定__GFP_HIGHMEM,故

不限于HIGHMEM,也可以用NORMAL;VM_MAP仅申请线性地址;

VM_IOREMAP仅申请线性地址,其物理内存一般都是超高的.

第四部分slab

slab是一种通用小块数据结构缓存机制,使用它的原因是

1.频繁分配释放,故需要缓存

2.频繁的结果是导致内存碎片,即找不到大的连续内存.为了避免,需要将空闲内存连续存放.

可见,slab主要还是解决连续性这个问题的,至于内碎片的浪费,并没避免.

3.回收后即可立即使用,这样提高了效率.

4.对对象着色,这样防止多个对象映射到同一个高速缓存行时,导致切换对象访问引起的颠簸.

每种slab对应一个高速缓存.

申请slab,其实是调用__get_free_pages()得到内存的,

故slab申请的空间也是从低端内存得到的.

kmalloc()其实是基于slab的,使用了一组通用的高速缓存.

第五部分 结合代码分析

还是得附上code基础上聊聊高端内存,因为linux的内存管理中,理解高端内存很重要.

内核要管理4G空间,但是其线性空间仅为1G,这个是为了留出3G给用户空间的.

如果1G全部直接映射,则内核仅能寻址1G空间了,所以又留出128M给动态映射.

这样896M的直接映射+128M的动态映射(重复用)就够4G了.所有物理内存对应的

vm_page肯定都在直接映射区,但是如果访问的话就需要MMU准备映射了.

高端内存是指高于896M的部分,其有3种映射方式:

1.动态

通过vmalloc()申请,获得连续的线性空间.

2.永久

通过alloc_page()有可能是高端内存,此时需要获得PKMAP_BASE到FIXADDR_START

的4M(即pkmap_page_table代表一页页表)的永久映射,

通过kmap()即可将该page映射到该线性空间中.

特点是可能睡眠,因为数量有限.

3.临时

即FIXADDR_START到FIXADDR_TOP之间的空间,用kmap_atomic()获得.

每个cpu都有自己的临时映射空间,独立的.这部分空间又分为分page,每个page代表一个

功能.

特点就是禁止本cpu中断,不睡眠,可直接使用,其实就是直接覆盖上一个.

max_low_pfn = max_pfn;

#ifdef CONFIG_HIGHMEM

highstart_pfn = highend_pfn = max_pfn;

if (max_pfn > MAXMEM_PFN) {

highstart_pfn = MAXMEM_PFN;

printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",

pages_to_mb(highend_pfn - highstart_pfn));

}

#endif

可见:

刚开始把所有物理内存a都看做低端内存,

然后看a<=896M,则高端内存起始为a,终止为a.

如果a>896M,则高端起始为896M,终止为a.

所以高端内存是一个物理内存的概念.

#ifdef CONFIG_HIGHMEM

highmem_start_page = mem_map + highstart_pfn;

max_mapnr = num_physpages = highend_pfn;

#endif

high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);

可见:

high_memory即高端内存, 是从max_low_pfn(16M<=max_low_pfn<=896M)开始的,

所以高端内存是从b(16M<=b<=896M)开始的,具体依赖于实际的内存大小.

#define VMALLOC_OFFSET (8*1024*1024)

#define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \

~(VMALLOC_OFFSET-1))

可见:

VMALLOC_START是从high_memory+空洞(8M

同样,在各个vmallco()分配得到的各个线性空间之间也有8k大小的空洞.

这些都是为了防止越界的.

第六部分 最后的结论

内核映像和mem_map[]开始于虚拟空间的3G+16M处,前16M用于DMA.

vmalloc()的作用就是将不连续物理内存映射到连续线性空间,

VMALLOC_RESERVE大小(128M)的空间就用于vmalloc()/永久/临时映射使用,

虽然在a<896M的情况下,内核其实可以有>128M的保留线性空间.

所以,

高端内存起址为b(896M>=b>=16M),但保留区间大小恒为128M,

而这就间接导致ZONE_NORMAL区的大小是0M到(896-b)M.

by chishanmingshen:x86已经很过时了,下次开始分析x64!

http://www.lbrq.cn/news/2638315.html

相关文章:

  • 网站建设的功能有哪些建网站需要哪些步骤
  • 公司基础建设的意义湖南seo优化价格
  • 邢台哪里做网站湖南seo推广多少钱
  • 做的好的购物网站目前搜索引擎排名
  • 类网站建设淘宝代运营1个月多少钱
  • 莱芜做网站的商家有哪些常德今日头条新闻
  • 最便宜网站推广公司产品
  • 网站的主题网站浏览器
  • 沈阳网站做app推广公司
  • ubuntu server wordpress石家庄seo网站管理
  • 免费推广seo本溪seo优化
  • 靖江网站微信营销软件免费版
  • 龙岩电商公司seo搜索引擎排名优化
  • 合肥晨曦网站建设互联网营销师证书
  • 鞍山建设工程信息网站武汉推广服务
  • 怎么做创业网站爱站工具
  • 重庆做商城网站设计免费建网页
  • 用.net core 做网站google chrome
  • 泰州网站建设服务热线论文关键词
  • 网站建设 自己的服务器电商推广
  • 自己做的网站响应速度慢百度推广的步骤
  • 深圳方维网站建设seo顾问服务 乐云践新专家
  • 专业做网站咨询seo点击排名器
  • 了解网站建设企业seo整站优化方案
  • 二级域名购买平台优化设计英语
  • 成都微信网站建设多少优化关键词方法
  • 上海景点排名前十久久seo综合查询
  • 域名解析网站建设少女长尾关键词挖掘
  • 校园超市网站开发背景百度正版下载并安装
  • app制作网站有哪些 请列举网站及搜索引擎优化建议
  • 51c视觉~合集16
  • 【优选算法】BFS解决拓扑排序
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十天-面试第一天
  • selenium操作指南
  • Redis里面什么是sdshdr,可以详细介绍一下吗?
  • 使用DrissionPage实现xhs笔记自动翻页并爬取笔记视频、图片