首页
社区
课程
招聘
[求助]看《Windows核心编程》有地方不明白请大虾指教
发表于: 2008-6-17 14:13 5298

[求助]看《Windows核心编程》有地方不明白请大虾指教

2008-6-17 14:13
5298
13.6.1 Copy-On-Write访问

表1 3 - 2列出的保护属性都是非常容易理解的,不过最后两个属性需要作一些说明。一个是PA G E _ W R I T E C O P Y,另一个是PA G E _ E X E C U T E _ W R I T E C O P Y。这两个属性的作用是为了节省R A M的使用量和页文件的空间。Wi n d o w s支持一种机制,使得两个或多个进程能够共享单个内存块。因此,如果1 0个N o t e p a d实例正在运行,那么所有实例可以共享应用程序的代码和数据页面。让所有实例共享同样的内存页面将能够大大提高系统的性能,但是这要求所有实例都将该内存视为只读或只执行的内存。如果一个实例中的线程将数据写入内存修改它,那么其他实例看到的这个内存也将被修改,从而造成一片混乱。

为了防止出现这种混乱,操作系统给共享内存块赋予了C o p y - O n - Wr i t e保护属性。当一个. e x e或D L L模块被映射到一个内存地址时,系统将计算有多少页面是可以写入的(通常包含代码的页面标为PA G E _ E X E C U T E _ R E A D,而包含数据的页面则标为PA G E _ R E A D W R I T E)。然后,系统从页文件中分配内存,以适应这些可写入的页面的需要。除非该模块的可写入页面是实际的写入模块,否则这些页文件内存是不使用的。

当一个进程中的线程试图将数据写入一个共享内存块时,系统就会进行干预,并执行下列操作步骤:

1) 系统查找R A M中的一个空闲内存页面。注意,当该模块初次被映射到进程的地址空间时,该空闲页面将被页文件中已分配的页面之一所映射。当该模块初次被映射时,由于系统要分配所有可能需要的页文件,因此这一步不可能运行失败。

【1】
橙色部分是不是这个意思啊:系统发现一个EXE或者DLL文件有N页是可以写入的,那么就在页文件中分配N页内存,然后把EXE或者DLL的那N页数据拷贝到页文件的那N页中去?那如果是这样的话,不可写的部分怎么办?难道直接在RAM中分配内存来容纳?
【2】
红色部分看半天也没明白。为什么RAM中的空闲页面会被页文件中的页面映射?感觉莫明其妙啊?
英文原文:Note that this free page will be backed by one of the pages allocated in the paging file when the module was first mapped into the process's address space.
这个英文中用的是“BACK”不知是什么意思?

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 259
活跃值: (26)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
2
我发表一下个人见解哈,映射并不是说直接将你的dll写到内存,不然的话系统有这么多dll,你的电脑的物理内存+虚存估计都不够用,那么映射就是系统给你做了一个硬盘文件的地址和所谓的内存地址关系,这样我们看起来就有了所谓的4GB的控件。

好像是这样,这些该概念我也记得不是很清楚了
2008-6-17 15:07
0
雪    币: 259
活跃值: (26)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
3
如果有10个notepad被执行,那么如果他们的可写页面被共享,肯定是不行的,因此,为了防止干扰,系统会对每一个被改变的页面分配新的页面,并将老的数据copy过去,修改后的数据是在新的页面修改的,因此,其他进程是不会受到干扰的
2008-6-17 15:12
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
那这样的话,橙色部分怎么理解了呢?
当一个. e x e或D L L模块被映射到一个内存地址时,系统将计算有多少页面是可以写入的(通常包含代码的页面标为PA G E _ E X E C U T E _ R E A D,而包含数据的页面则标为PA G E _ R E A D W R I T E)。然后,系统从页文件中分配内存,以适应这些可写入的页面的需要。
感觉从这句话来理解的话,模块被映射的时候,其内部被分成了可以写入的、不可以写入的两个部分。可以写入的部分所对应的物理内存在页文件中,不可以写入的部分所对应的物理内存在哪里没说(不过我想除了页文件,只有RAM了啊)

映射应该确实是反映的您说的一种对应关系,但是应该是地址空间与RAM或者页文件的对应关系吧。
2008-6-17 16:47
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我是这样想的,基本和您的观点一样。
可写页面,根据橙色部分的话,其物理内存在页文件里。现在要改写,根据COPY-ON-WRITE机制,系统会新分配一个页面出来,把老的数据COPY过去。
1) 系统查找R A M中的一个空闲内存页面。注意,当该模块初次被映射到进程的地址空间时,该空闲页面将被页文件中已分配的页面之一所映射。当该模块初次被映射时,由于系统要分配所有可能需要的页文件,因此这一步不可能运行失败。

参照红色部分的话,这个新页面是在RAM中查找的,而且还说这个新页面一定是存在的。
“该空闲页面将被页文件中已分配的页面之一所映射”
这句话到底什么意思呢?
2008-6-17 17:05
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
黄色字部分和unix的fork()系统调用的某些机制没有差别。
我来说一下unix的这种情况:
简单来说就是fork调用会复制调用的父进程来产生子进程。为了节省内存和提高效率,父和子进程的内存内容是一样的,主要是变量和程序的一样,也就是进程的数据段和代码段的一样,其实就是用的同一块的内存!只有实际使用的使用才会实际复制出一个不同的数据段(怎么是实际使用?当然是子进程和父进程的各种数组变量的不同改变了),但是代码段没有必要修改,两个进程代码段是一样的,其实就是同一块内存,实际区别是子进程的fork返回-1,但是父进程的返回创建的进程ID(是子进程的).用一个if判断来执行父子进程不同的代码。
C o p y - O n - Wr i t e,名字就很形象。write是一个动词,copy也是动词,意思就是:在写入的时候copy。不写入内存就共享一个程序的内存就可以了。10个文本程序都不写入没有必要分配10个文本程序的空间,分配一个就好了。一旦开写就copy一个副本来操作。

和unix的这个传统技术很相像啊。但是不同也是有的,包括了写入内存不是真要写就不进入内存,而是在硬盘的页文件中分配。页文件也就是虚拟内存吧。
2008-6-18 00:41
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
1) 系统查找R A M中的一个空闲内存页面。注意,当该模块初次被映射到进程的地址空间时,该空闲页面将被页文件中已分配的页面之一所映射。
-----------------------------------------------------------------
前边已经说了:系统从页文件中分配内存,以适应这些可写入的页面的需要。除非该模块的可写入页面是实际的写入模块,否则这些页文件内存是不使用的。

也就是说如果真的要写入的话,找一块空闲内存,然后把过去放在了页文件里的可写入内存提回了真的RAM

当该模块初次被映射时,由于系统要分配所有可能需要的页文件,因此这一步不可能运行失败。
---------------------------------------------------------------------------------------------
映射是什么时候?就是下边这个时候:

然后,系统从页文件中分配内存,以适应这些可写入的页面的需要。(黄色字的部分)

那时候已经映射了。在页文件里呢。微软说:不可能失败。(这里不晓得理解是否有误。)

偶是学习linux程序设计的。这些东西也就到这里。不妥之处多多指教。
2008-6-18 01:01
0
游客
登录 | 注册 方可回帖
返回
//