Linux内核中内存管理相关的数据结构
来源:互联网 发布:跨平台app开发 知乎 编辑:程序博客网 时间:2024/05/21 16:22
本文简要说明几个内核和内存管理有关的结构体。其中 struct page 和 struct zone有较大幅度的删减,主要删减了和NUMA模型SPARSE模型以及内存热插拔相关的域。
页框描述符 struct page
page用于描述一个4KB的物理页。MMU以页为单位管理页表。
struct page { unsigned long flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; struct list_head lru; void *virtual; };
(1) flag 单独的每一位用来表示一种状态,所以在32位的CPU上flag至少能表示32状态,而在64位的CPU上则至少能表示64种状态。但是,实际上,page的flag被分成高低两个部分,以32位CPU为例 :
| FIELD | ... | FLAGS | N-1 ^ 0 (NR_PAGEFLAGS)
(2) _count用来表示该页框被引用的次数,一个物理页可以同时被多个虚拟页面映射。内核通过 page_count() 来获取页的引用计数。
(3) _mapcount 引用该页框的页表项(PTE)个数,当使用fork()时,do_fork()调用的copy_mm()会使得该值加一。
(4) private 是一个指向私有数据的指针,虚拟内存管理并不会使用该数据,而是根据页的用途,各个模块以不同的方式使用它。比如在页作为页缓冲时它是缓冲区的头指针。如果页是空闲的,则该字段由伙伴系统使用。
(5) lru 构成了一个最近最少被使用的页的链表,处于该链表中的页即将被page out。
内存区域描述符 struct zone
struct zone { unsigned long watermark[NR_WMARK]; struct per_cpu_pageset __percpu *pageset; spinlock_t lock; int all_unreclaimable; /* All pages pinned */ struct free_area free_area[MAX_ORDER]; spinlock_t lru_lock; struct zone_lru { struct list_head list; } lru[NR_LRU_LISTS]; struct zone_reclaim_stat reclaim_stat; unsigned long pages_scanned; unsigned long flags; atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; int prev_priority; unsigned int inactive_ratio; struct pglist_data *zone_pgdat; unsigned long zone_start_pfn; unsigned long spanned_pages; unsigned long present_pages; } ____cacheline_internodealigned_in_smp;
(1) watermark
系统的空闲内存有三种状态:
WMARK_MIN,
WMARK_LOW,
WMARK_HIGH,
当系统中空闲内存低于watermark[low]时,开始启用内核守护线程kswapd进行内存页面回收(每个zone中都会有一个kswapd),直到该zone的空闲内存页数量达到watermark[high]之后才停止回收行为。如果上层申请内存的速度太快,导致空闲内存降至watermark[min]以下,内核就会进行direct reclaim(直接回收),也就是说直接在应用程序的上下文中进行页面回收,再用回收来的内存满足内存申请。所以,当有这样的情况发生时就会阻塞应用程序的执行,会带来一定的响应延迟,甚至可能会触发OOM(Out Of Memory,内存溢出)。因为watermark[min]以下的内存空间是留给系统特殊使用的,所以不会给用户态程序用。
(2) lock 保护该描述符的锁
(3) free_area 指向该zone中的空闲页块
struct zonelist
zonelist是一个zone的链表。一次分配的请求是在zonelist上执行的。开始在链表的第一个zone上分配,如果失败,则根据优先级降序访问其他zone。
zlcache_ptr 指向zonelist的缓存。为了加速对zonelist的读取操作 ,用_zonerefs 保存zonelist中每个zone的index。
struct zonelist { struct zonelist_cache *zlcache_ptr; // NULL or &zlcache struct zoneref _zonerefs[MAX_ZONES_PER_ZONELIST + 1];};
struct per_cpu_pages
由于页框频繁的分配和释放,内核在每个zone中放置了一些事先保留的页框。这些页框只能由来自本地CPU的请求使用。
struct per_cpu_pages { int count; /* number of pages in the list */ int high; /* high watermark, emptying needed */ int batch; /* chunk size for buddy add/remove */ /* Lists of pages, one per migrate type stored on the pcp-lists */ struct list_head lists[MIGRATE_PCPTYPES];};
(1) count:表示高速缓存中的页框数量。
(2) high :缓存中页框数量的最大值
(3) batch :buddy allocator增加或删除的页框数
(4) lists:页框链表。
reference
http://blog.chinaunix.net/uid-27177626-id-4197018.html
http://lib.csdn.net/article/linux/40867
- Linux内核中内存管理相关的数据结构
- linux内核-----内存管理相关技术
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数-2
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数
- linux内核中内存相关的操作函数
- Linux内核中内存相关的操作函数-1
- Linux内核中内存相关的操作函数-2
- Linux内核中内存相关的操作函数
- Linux内核中断相关的数据结构 (三)
- linux内核源码分析(内存管理)--之数据结构
- linux内核源代码学习(4)关于一些数据结构和用户内存的管理
- Android 自定义线程池
- 释放资源
- unity优化《三》--将包大小减少到极致
- 前端实现下拉显示更多功能
- 使用Lint工具进行代码分析
- Linux内核中内存管理相关的数据结构
- SQL执行顺序
- 求三个数的最大值(利用三目运算符)
- 大话数据结构读书笔记(5)----图
- java获取扫描枪的数据到数据库
- HDU-5559-Frog and String
- 实验二(顺序表)
- 680. Valid Palindrome II
- 20171016笔记