未完待续
概念
物理内存
即
windows
可用的物理内存
已
缓
存
内存
对
象中的一些性能
计
数器
总
合,包括
Cache Bytes
,
Modified Page List Bytes, Standby Cache Core Bytes
,
Standby Cache Normal Priority Bytes
,以及 Standby Cache Reserve Bytes
可用
可以由操作系
统
,
进
程,
驱动
程序立即使用的物理内存数量,它等于
备
用(
standby
) ,空闲
(
free
),以及零
页
列表(
zero page lists
)三者之和。
空
闲
空
闲页
和零
页
列表中的
页
面
总
字
节
内核内存、
分
页
数
分
页
池的
总
字
节
,包含空
闲
和已分配区域;
未分
页
数
不可分
页
池的
总
字
节
,包含空
闲
和已分配区域;
System: Commit
系
统栏
位中的
“
提交
”
前后
显
示
2
个数字,分
别
等于
Committed Bytes
和
Commit Limit
这
2
个性能
计
数器;
工具:
Process Explorer
(
进
程
浏览
器或
进
程
资
源管理器)能
够显示更多有关物理内存和虚 拟
内存的数据
VMMap
将一个
进
程内的虚
拟
内存使用情况
显
示到一个极端
细
致的水平;
RAMMap
显
示物理内存使用情况的
细节
;
内存管理器
内存管理器必
须对
其
访问进
行同步化的一些系
统
范
围资
源包括:
■
系
统
虚
拟
地址空
间
的
动态
分配部分;
■
系
统
工作集;
■
内核内存池;
■
已加
载驱动
程序的列表;
■
分
页
文件列表;
■
物理内存列表;
■
地址空
间
布局随机化(
ASLR
)使用的相关
结
构
内存管理器提供的服务
内存管理器提供一组系统服务用于
1、分配和释放虚拟内存,
2、在进程间共享内存,
3、将磁盘 文件映射至内存,
4、将虚拟页刷新到磁盘,
5、检索一系列有关虚拟页的信息,
6、更改虚拟页 的保护属性,
7、以及将虚拟页锁在内存中。
3组内存API
这
些服
务绝
大多数通
过
Windows API
对
外暴露。
Windows API
中有
3
组
函数用于管理
应用程序内存:
1、堆函数
(
Heapxxx
以及旧版接口
Localxxx
与
Globalxxx
,后
2
者在内部利用
Heapxxx APIs),它
们
可能被用来分配小于一
页
的内存;
2、虚拟
内存函数
(
Virtualxxx
),它
们
可用来操作
页
面的粒度(
详
情参考
“
大
页
面与小
页 面”
一
节
);
3、内存映射文件函数
(
CreateFileMapping
,
CreateFileMappingNuma
,
MapViewOfFile ,MapViewOfFileEx
,以及
MapViewOfFileExNuma
)
大页面与小页面
虚
拟
地址空
间
被划分
为
叫做
页
面的
单
元。
这
是由于硬件内存管理
单
元(
译
注:即
MMU )以页
面
为
粒度将虚
拟
地址翻
译成物理地址。
于是,在硬件
级别
,一个
页
就是最小的
保
护单
元。
大
页
面的主要
优势
是加快引用
页
面内其它数据的地址翻
译速度。原因将
导
致
CPU
内部的TLB,
对
于一个
4MB
地址空
间
范
围
,需要
1024
个
4KB
小
页
面;只需要
1
个
4MB
大
页面就能覆盖,因
为页
表通常在内存中,内存
访问
比
TLB
访问
至少慢上2个数量级。
TLB
一般可以存
储
64
个
PTE
条目,如果使用每个
PTE
映射
4KB
地址空
间
的小 页面,那么
总
共能
缓
存
4*64 = 256KB
的物理地址空
间
,如果使用
4MB
的大
页
面,
则
可 以缓
存
4*64=256MB
的物理地址空
间
如何使用大页面
1、(通
过
在
VirtualAlloc
, VirtualAllocEx,以及
VirtualAllocExNuma
函数参数中指定
MEM_LARGE_PAGE
标 志)
2、
HKLM\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\
添加一个名
为
“LargePageDrivers”
的多字符串
值
大
页
面有个令人
遗
憾的副作用
1、的
单
一保
护
策略
进行映射,如果一个大
页
面包含只
读
代
码
与可
读
写的数据,
该页
面必
须
被
标记为
可
读
写
保留的与提交的页面
一个
进
程虚
拟
地址空
间
中的
页
面可能属于下列一种:
free
(空
闲
的)
, reserved(保留的)
, committed
(提交的)
, shareable
(可共享的)
提交和共享的
页
面在被
访问时
,最
终
将
转换
(翻
译
)成物理内存中合法有效的页面
试图访问
空
闲
的(
free
)和保留的(
reserved
)内存会
导致一个 异常 ,
因为这些虚拟页面没有映射到任何能够解析该引用的存储器位置
私有
页
面是通
过
Windows
函数
VirtualAlloc, VirtualAllocEx,
以及
VirtualAllocExNuma
分 配的
这
些函数允
许
一个
线
程
预
留出地址空
间
,然后提交部分的
预
留空
间
(作
为私有 页
面使用)
使用testlimit 测试概念
设识别
到的物理内存
总
量
为
3GB
,并且
设
置了初始大小
为
2GB
的分
页
文件,那么 system commit limit的
值为5GB。
如果所有当前运行的
进
程被分配的虚
拟
内存
总合达 到
这
个限制,新的
进
程将无法运行,
windows
会
给
出
页
面文件太小,无法
执
行
应用程序的
错误
提示。
而推荐
设
置的
页
面文件大小通常是
识别
出的物理内存的
1.5~2倍; 这
意味着
32
位
windows
的
页
面文件大小
为
4.5~6GB
,
则
system commit limit
的
值
就为 7.5~9GB
共享内存和映射文件
当一个共享的页面首次被任何进程访问时,将从(磁盘上)关联的映射文件读入内存
映 射文件的页面也可以被写回它们在磁盘上的原始文件,这通过两种方法实现:显式调 用FlushViewOfFile函数;或者通过映射页面回写器
“
回收的
”
与
“
释
放
”
之
间
的区
别
,
类
似于
“
保留的
”
与
“
提交的
”
之
间
的区
别
——
回收的内存仍然是被保留的,而释
放的内存就已
经
被
释
放了(
has been freed
);它既不属于提交的,也不属于保留的
锁定内存
一般而言,最好让内存管理器决定哪些页面保留在物理内存中。然而,可能出现应用 程序或设备驱动程序有必要在物理内存中锁定页面的特殊情况。有2种途径可以将页面 锁在内存中:
1、Windows应用程序可以调用VirtualLock函数
2、对于设备驱动程序,可以调用内核模式函数MmProbeAndLockPages, MmLockPagableCodeSection,MmLockPagableDataSection,或者 MmLockPagableSectionByHandle。
分配粒度 ?
Windows
将每个保留的
进
程地址空
间
区域,按照一个完整的
边
界
为
起始
进
行
对齐
,
这由系统
分配粒度
值
定
义
,
该值
可以通
过
Windows
函数
GetSystemInfo
或 GetNativeSystemInfo 检索。
这
个
值
的大小
为64KB是被内存管理器使用的一个粒度,用于高效分配元数据
最后,当地址空
间
的一个区域
为
保留的,
Windows
确保
该区域的大小和基址是一个多 重系
统页
面大小,无
论
它是多少。
举
例来
说
,由于
x86
系
统
使用
4KB
页
面,如果你尝试 保留一个
18KB
的内存区域,在
x86
系
统
上,
实际
的保留数量将会是
20KB
。如果你
为
一
个
18KB
大小的区域指定
3KB
的基址,
实际
的保留数量将会是
24KB
。注意,
对于分配 的
VAD
,随后也将舍入到
64KB
对齐
/
长
度,从而使得其剩余部分无法
访问
。
内存保护
1、所有内核模式系统组件使用的系统级别数据结构和内存池,硬件生成一个错 误,从而内存管理器反过来向该线程报告一个非法访问
2、每个进程有一个独立,私用的地址空间
3、硬件控制内存保护机制”(例如读/写,只读等等), VirtualProtect, VirtualProtectEx,VirtualQuery,以及VirtualQueryEx函数的说明文档
4、共享内存节对象有标准的Windows访问控制列表(ACLs)
不可执行页保护
不可
执
行
页
保
护
(也被称
为
数据
执
行保
护
,或
DEP
)
导
致
试图转
移(
对
CPU的)控制 到一个
标记为
“
不可
执
行
”
页
中的指令
时
,生成一个
访问错误
。
这
可以防止某些
类型的 恶
意
软
件通
过
将可
执
行代
码
放置在比如
栈这
种数据
页
中,从而利用系
统
中的缺陷或漏
洞。
写时复制
地址窗口化扩展
概念名词
物理地址
扩
展(
PAE
)
页
表条目(
PTE
)
数据
执
行保
护
,或
DEP
地址窗口化
扩
展 (AWE
)的