内存管理

一、内存初始化

1、内存的初始化一般由BIOS或boot loader完成,由bios或boot loader将内存的大小传递给linux内核

2、在arm设备中,设备由DTS(Device Tree Source)描述,安卓中也是如此

3、在内核启动过程中,需要解析dts文件,其中使用early_init_dt_scan_memory()函数来解析内存信息,解析内存相关的信息得到基地址(base address)和大小(size),最后通过memblock_add()函数添加到memblock中

4、memblock是一种早期内存分配器,用于在内核启动初期进行简单的内存管理

5、在内存映射时,需要首先清理页表(prepare_page_table()->pmd_clear()),然后创建新的页表(map_lowmem()->create_mapping()),完成初始化

6、上述的初始化过程(物理内存映射)会从内存开始处(dts中)覆盖至arm_lowmem_limit处

7、紧接着会进行zone初始化,主要在bootmem_init函数中完成

8、zone初始化完成后,内核会进行空间划分,通常用户空间和内核空间按照3:1划分

二、物理页面分配

1、内核使用alloc_pages()函数来分配一个或多个了i按需的物理页面,但分配的页面只能是2的整数幂次个

2、

三、内存管理

1、内存节点的概念是针对大型机器(多处理器机器)而提出的,单处理器机器中也有这个机制(硬件兼容性),只不过只使用一个节点来管理内存

2、在NUMA模式下,CPU被划分成多个节点,根据处理器访问内存的代价(距离)不同,将不同的内存簇指派给不同的处理器,这样的内存簇被认为是一个内存节点

3、节点被分为许多zone,由zone结构体描述,在安卓使用的Linux内核中,定义了ZONE_DMA,ZONE_DMA32,ZONE_HIGHMEM,ZONE_NORMAL

4、节点、zone、页关系如下图

Untitled.png/

5、zone结构体字段及作用如下(新版源码中还包含有其他字段)

字段 描述
watermark 每个 zone 在系统启动时会计算出 3 个水位值, 分别为 WMAKR_MIN, WMARK_LOW, WMARK_HIGH 水位, 这在页面分配器和 kswapd 页面回收中会用到
lowmem_reserve[MAX_NR_ZONES] zone 中预留的内存, 为了防止一些代码必须运行在低地址区域,所以事先保留一些低地址区域的内存
pageset page管理的数据结构对象,内部有一个page的列表(list)来管理。每个CPU维护一个page list,避免自旋锁的冲突。这个数组的大小和NR_CPUS(CPU的数量)有关,这个值是编译的时候确定的
lock 对zone并发访问的保护的自旋锁
free_area[MAX_ORDER] 页面使用状态的信息,以每个bit标识对应的page是否可以分配
lru_lock LRU(最近最少使用算法)的自旋锁
wait_table 待一个page释放的等待队列哈希表。它会被wait_on_page(),unlock_page()函数使用. 用哈希表,而不用一个等待队列的原因,防止进程长期等待资源
wait_table_hash_nr_entries 哈希表中的等待队列的数量
zone_pgdat 指向这个zone所在的pglist_data对象
zone_start_pfn 和node_start_pfn的含义一样。这个成员是用于表示zone中的开始那个page在物理内存中的位置的present_pages, spanned_pages: 和node中的类似的成员含义一样
name zone的名字,字符串表示: “DMA”,“Normal” 和“HighMem”
totalreserve_pages 每个区域保留的不能被用户空间分配的页面数目
ZONE_PADDING 由于自旋锁频繁的被使用,因此为了性能上的考虑,将某些成员对齐到cache line中,有助于提高执行的性能。使用这个宏,可以确定zone->lock,zone->lru_lock,zone->pageset这些成员使用不同的cache line.
managed_pages zone 中被伙伴系统管理的页面数量
spanned_pages zone 中包含的页面数量
present_pages zone 中实际管理的页面数量. 对一些体系结构来说, 其值和 spanned_pages 相等
lruvec LRU 链表集合
vm_stat zone 计数

6、zone的初始化在bootmem_init函数中完成

7、find_limit函数中会计算出min_low_pfn、max_low_pfn、max_pfn,其中min_low_pfn是内存块开始地址的页帧号,max_low_pfn是normal区结束的区帧号(这个值由arm_lowmem_init得来),max_pfn是内存块结束的页帧号

Q&A

1、 数据删除的原理是什么,如何将数据删除干净?

美国国防部在《国家工业安全程序操作手册》中对硬盘数据清除作了专门的描述。该手册建议对所要清除的数据区进行三次覆盖,第一次使用一个8位的字符,第二次使用该字符的互补字符,最后再使用随机字符进行覆盖。保存有极端重要数据的硬盘应该被永久消磁或者彻底销毁。

对于数据删除,本质上讲是将想要删除的数据标所对应空间标记为空闲,让对应空间可以重新储存数据,但是原先的数据仍旧存在。

对于Linux来说,删除文件的行为是将inode结构体中的i_nlink字段(硬链接数目)值减少,直到i_nlink 和 i_count 均为 0 时,文件被删除,也就是说文件名到inode的链接删除了,磁盘上的数据块并未被删除

2、数据恢复的方法和原理都是什么

在Linux下恢复数据,ext3和ext4文件系统中的元数据在日志文件中的备份来进行恢复,但日志文件空间优先且是循环使用的,所以经历大量读写后可能无法恢复。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇