【Linux 内核 内存管理】物理内存组织结构 ④ ( 内存区域 zone 简介 | zone 结构体源码分析 | zone 结构体源码 )
文章目录
- 一、内存区域 zone 简介
- 二、zone 结构体源码分析
- 1、watermark 成员
- 2、lowmem_reserve 成员
- 3、zone_pgdat 成员
- 4、pageset 成员
- 5、zone_start_pfn 成员
- 6、managed_pages、spanned_pages、present_pages成员
- 7、name 成员
- 8、free_area 成员
- 三、zone 结构体源码
内存管理系统 333级结构 :
① 内存节点 Node ,
② 内存区域 Zone ,
③ 内存页 Page ,
Linux 内核中 , 使用 上述 333 级结构 描述 和 管理 " 物理内存 " ;
一、内存区域 zone 简介
" 内存节点 " 是内存管理的 最顶层结构 ,
" 内存节点 " 再向下划分 , 就是 " 内存区域 " zone ,
" 内存区域 " 在 Linux 内核中使用 struct zone
结构体类型进行描述 , zone
枚举定义在 Linux 内核源码的 linux-4.12\include\linux\mmzone.h#350 位置 ;
每个 " 内存区域 " , 都使用 111 个 zone
结构体 描述 ;
二、zone 结构体源码分析
1、watermark 成员
watermark
表示 " 页分配器 " 使用的 水线 ;
/* zone watermarks, access with *_wmark_pages(zone) macros */unsigned long watermark[NR_WMARK];
2、lowmem_reserve 成员
lowmem_reserve
表示 页分配器 使用的 区域 , 这些区域 必须 保留 , 不能借给高区域类型 ;
/** We don't know if the memory that we're going to allocate will be* freeable or/and it will be released eventually, so to avoid totally* wasting several GB of ram we must reserve some of the lower zone* memory (otherwise we risk to run OOM on the lower zones despite* there being tons of freeable ram on the higher zones). This array is* recalculated at runtime if the sysctl_lowmem_reserve_ratio sysctl* changes.*/long lowmem_reserve[MAX_NR_ZONES];
3、zone_pgdat 成员
zone_pgdat
指向 " 内存节点 " 的 pglist_data
实例 ;
struct pglist_data *zone_pgdat;
4、pageset 成员
pageset
表示 每个 " 处理页 " 的集合 ;
struct per_cpu_pageset __percpu *pageset;
5、zone_start_pfn 成员
zone_start_pfn
表示当前 " 内存区域 zone " 的 " 起始物理页 " 编号 ;
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */unsigned long zone_start_pfn;
6、managed_pages、spanned_pages、present_pages成员
managed_pages
表示 " 伙伴分配器 " 管理的 物理页数量 ;
spanned_pages
表示 当前的 " 内存区域 " 跨越的 物理页 个数 , 包含 " 内存空洞 " ;
present_pages
表示 当前的 " 内存区域 " 包含的 物理页 个数 , 不包含 " 内存空洞 " ;
/** spanned_pages is the total pages spanned by the zone, including* holes, which is calculated as:* spanned_pages = zone_end_pfn - zone_start_pfn;** present_pages is physical pages existing within the zone, which* is calculated as:* present_pages = spanned_pages - absent_pages(pages in holes);** managed_pages is present pages managed by the buddy system, which* is calculated as (reserved_pages includes pages allocated by the* bootmem allocator):* managed_pages = present_pages - reserved_pages;** So present_pages may be used by memory hotplug or memory power* management logic to figure out unmanaged pages by checking* (present_pages - managed_pages). And managed_pages should be used* by page allocator and vm scanner to calculate all kinds of watermarks* and thresholds.** Locking rules:** zone_start_pfn and spanned_pages are protected by span_seqlock.* It is a seqlock because it has to be read outside of zone->lock,* and it is done in the main allocator path. But, it is written* quite infrequently.** The span_seq lock is declared along with zone->lock because it is* frequently read in proximity to zone->lock. It's good to* give them a chance of being in the same cacheline.** Write access to present_pages at runtime should be protected by* mem_hotplug_begin/end(). Any reader who can't tolerant drift of* present_pages should get_online_mems() to get a stable value.** Read access to managed_pages should be safe because it's unsigned* long. Write access to zone->managed_pages and totalram_pages are* protected by managed_page_count_lock at runtime. Idealy only* adjust_managed_page_count() should be used instead of directly* touching zone->managed_pages and totalram_pages.*/unsigned long managed_pages;unsigned long spanned_pages;unsigned long present_pages;
7、name 成员
name
表示 " 内存区域 " 名称 ;
const char *name;
8、free_area 成员
free_area
表示 不同长度的 内存空间区域 ;
/* free areas of different sizes */struct free_area free_area[MAX_ORDER];
三、zone 结构体源码
zone
结构体源码 :
struct zone {/* Read-mostly fields *//* zone watermarks, access with *_wmark_pages(zone) macros */unsigned long watermark[NR_WMARK];unsigned long nr_reserved_highatomic;/** We don't know if the memory that we're going to allocate will be* freeable or/and it will be released eventually, so to avoid totally* wasting several GB of ram we must reserve some of the lower zone* memory (otherwise we risk to run OOM on the lower zones despite* there being tons of freeable ram on the higher zones). This array is* recalculated at runtime if the sysctl_lowmem_reserve_ratio sysctl* changes.*/long lowmem_reserve[MAX_NR_ZONES];#ifdef CONFIG_NUMAint node;
#endifstruct pglist_data *zone_pgdat;struct per_cpu_pageset __percpu *pageset;#ifndef CONFIG_SPARSEMEM/** Flags for a pageblock_nr_pages block. See pageblock-flags.h.* In SPARSEMEM, this map is stored in struct mem_section*/unsigned long *pageblock_flags;
#endif /* CONFIG_SPARSEMEM *//* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */unsigned long zone_start_pfn;/** spanned_pages is the total pages spanned by the zone, including* holes, which is calculated as:* spanned_pages = zone_end_pfn - zone_start_pfn;** present_pages is physical pages existing within the zone, which* is calculated as:* present_pages = spanned_pages - absent_pages(pages in holes);** managed_pages is present pages managed by the buddy system, which* is calculated as (reserved_pages includes pages allocated by the* bootmem allocator):* managed_pages = present_pages - reserved_pages;** So present_pages may be used by memory hotplug or memory power* management logic to figure out unmanaged pages by checking* (present_pages - managed_pages). And managed_pages should be used* by page allocator and vm scanner to calculate all kinds of watermarks* and thresholds.** Locking rules:** zone_start_pfn and spanned_pages are protected by span_seqlock.* It is a seqlock because it has to be read outside of zone->lock,* and it is done in the main allocator path. But, it is written* quite infrequently.** The span_seq lock is declared along with zone->lock because it is* frequently read in proximity to zone->lock. It's good to* give them a chance of being in the same cacheline.** Write access to present_pages at runtime should be protected by* mem_hotplug_begin/end(). Any reader who can't tolerant drift of* present_pages should get_online_mems() to get a stable value.** Read access to managed_pages should be safe because it's unsigned* long. Write access to zone->managed_pages and totalram_pages are* protected by managed_page_count_lock at runtime. Idealy only* adjust_managed_page_count() should be used instead of directly* touching zone->managed_pages and totalram_pages.*/unsigned long managed_pages;unsigned long spanned_pages;unsigned long present_pages;const char *name;#ifdef CONFIG_MEMORY_ISOLATION/** Number of isolated pageblock. It is used to solve incorrect* freepage counting problem due to racy retrieving migratetype* of pageblock. Protected by zone->lock.*/unsigned long nr_isolate_pageblock;
#endif#ifdef CONFIG_MEMORY_HOTPLUG/* see spanned/present_pages for more description */seqlock_t span_seqlock;
#endifint initialized;/* Write-intensive fields used from the page allocator */ZONE_PADDING(_pad1_)/* free areas of different sizes */struct free_area free_area[MAX_ORDER];/* zone flags, see below */unsigned long flags;/* Primarily protects free_area */spinlock_t lock;/* Write-intensive fields used by compaction and vmstats. */ZONE_PADDING(_pad2_)/** When free pages are below this point, additional steps are taken* when reading the number of free pages to avoid per-cpu counter* drift allowing watermarks to be breached*/unsigned long percpu_drift_mark;#if defined CONFIG_COMPACTION || defined CONFIG_CMA/* pfn where compaction free scanner should start */unsigned long compact_cached_free_pfn;/* pfn where async and sync compaction migration scanner should start */unsigned long compact_cached_migrate_pfn[2];
#endif#ifdef CONFIG_COMPACTION/** On compaction failure, 1<<compact_defer_shift compactions* are skipped before trying again. The number attempted since* last failure is tracked with compact_considered.*/unsigned int compact_considered;unsigned int compact_defer_shift;int compact_order_failed;
#endif#if defined CONFIG_COMPACTION || defined CONFIG_CMA/* Set to true when the PG_migrate_skip bits should be cleared */bool compact_blockskip_flush;
#endifbool contiguous;ZONE_PADDING(_pad3_)/* Zone statistics */atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
} ____cacheline_internodealigned_in_smp;
源码路径 : linux-4.12\include\linux\mmzone.h#350
【Linux 内核 内存管理】物理内存组织结构 ④ ( 内存区域 zone 简介 | zone 结构体源码分析 | zone 结构体源码 )相关推荐
- 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )
文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...
- 【Linux 内核 内存管理】优化内存屏障 ④ ( 处理器内存屏障 | 八种处理器内存屏障 | 通用内存屏障 | 写内存屏障 | 读内存屏障 | 数据依赖屏障 | 强制性内存屏障 |SMP内存屏障 )
文章目录 一.处理器内存屏障 二.Linux 内核处理器内存屏障 一.处理器内存屏障 " 处理器内存屏障 " 针对 " CPU " 之间的内存访问乱序 和 CP ...
- Java内存管理:Java内存区域 JVM运行时数据区
Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程.Class文件结构.以及JVM字节码指令. 下面我们详细了解Java内存区域:先说明JVM规范定 ...
- JVM自动内存管理机制——Java内存区域(下)
一.虚拟机参数配置 在上一篇<Java自动内存管理机制--Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...
- Windows内存管理机密+揭穿内存优化工具的骗局
原文:The Memory-Optimization Hoax:RAM optimizers make false promises 作者:Mark Russinovich 译者:盆盆 我们在浏览 ...
- Linux内核页表管理-那些鲜为人知的秘密
1.开场白 环境: 处理器架构:arm64 内核源码:linux-5.11 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 通用操作系统,通常都会开启mmu来支持虚拟 ...
- Linux内核-进程管理
Linux内核-进程管理 引言 本文主要介绍Linux内核进程管理相关知识,包括进程描述符.进程创建.销毁.状态.线程的实现以及Linux进程相关命令等. 进程描述符 内核把进程的列表存放在叫做任务队 ...
- 【C 语言必知必会】内存管理、动态分配内存、野指针
C 语言内存管理.动态分配内存.野指针 文章目录 C 语言内存管理.动态分配内存.野指针 前言: 1.内存分区 1.1 代码区 1.2.1 全局初始化数据区(静态数据区data段) 1.2.2 未初始 ...
- 属性与内存管理(属性与内存管理都是相互关联的)
<span style="font-size:18px;"> 属性与内存管理(属性与内存管理都是相互关联的)第一部分一,属性:属性是OC2.0之后出来的新语法,用来取代 ...
- C++:内存管理:C++内存管理详解
C++语言内存管理是指:对系统的分配.创建.使用这一系列操作.在内存管理中,由于是操作系统内存,使用不当会造成很麻烦的后果.本文将从系统内存的分配.创建出发,并且结合例子来说明内存管理不当会造成的结果 ...
最新文章
- JVM生产环境参数实例及分析
- 3D Button Visual Editor
- netcore 内存限制_[翻译] 使用 Serverless 和 .NET Core 构建飞速发展的架构
- 怎么增加android模拟器内存卡,增加android模拟器的内存大小
- 网站微端服务器,微端服务器
- 适用于连续资源块的数组空闲链表的算法
- ffmpeg h264 h265 视频格式操作
- minimumsnap(1)微分平坦特性(Differential Flatness)
- 数字转为大写金额(C#)
- c语言函数字符传送,C语言中send()函数和sendto()函数的使用方法
- 机器学习算法工程师领域现状
- 雷霆传奇linux源码,【雷霆传奇H5服务端】2020.07首发超漂亮大翅膀传奇网页游戏客户端[附超详细搭建教程]...
- vue使用Echarts绘制自己股票K线图,包含数据接口
- vb.net产生随机数Random代码实例
- kaggle Notebook Threw Exception问题解决
- Xcode14 正式版编译报错‘ does not contain bitcode.解决方案
- 利用jsp写输入表单制作简历
- 千里之行,始于足下。python 爬虫 requestes模块(2)
- DSGN: Deep Stereo Geometry Network for 3D Object Detection---基于双目视觉的3D目标检测(1)
- P8大佬出书了!送送送!