<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>布谷屋</title>
	<atom:link href="http://www.buguw.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.buguw.com</link>
	<description>软件开发&#124;IT技术探讨&#124;互联网前沿</description>
	<lastBuildDate>Sat, 31 Dec 2011 09:48:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>数学之美番外篇：平凡而又神奇的贝叶斯方法[转]</title>
		<link>http://www.buguw.com/%e6%95%b0%e5%ad%a6%e4%b9%8b%e7%be%8e%e7%95%aa%e5%a4%96%e7%af%87%ef%bc%9a%e5%b9%b3%e5%87%a1%e8%80%8c%e5%8f%88%e7%a5%9e%e5%a5%87%e7%9a%84%e8%b4%9d%e5%8f%b6%e6%96%af%e6%96%b9%e6%b3%95%e8%bd%ac.html</link>
		<comments>http://www.buguw.com/%e6%95%b0%e5%ad%a6%e4%b9%8b%e7%be%8e%e7%95%aa%e5%a4%96%e7%af%87%ef%bc%9a%e5%b9%b3%e5%87%a1%e8%80%8c%e5%8f%88%e7%a5%9e%e5%a5%87%e7%9a%84%e8%b4%9d%e5%8f%b6%e6%96%af%e6%96%b9%e6%b3%95%e8%bd%ac.html#comments</comments>
		<pubDate>Sat, 31 Dec 2011 09:48:04 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[数据结构 & 算法]]></category>
		<category><![CDATA[贝叶斯]]></category>

		<guid isPermaLink="false">http://www.buguw.com/?p=264</guid>
		<description><![CDATA[数学之美番外篇：平凡而又神奇的贝叶斯方法 By 刘未鹏(pongba) C++的罗浮宫(http://blog.csdn.net/pongba) TopLanguage(http://groups.google.com/group/pongba) 概率论只不过是把常识用数学公式表达了出来。 ——拉普拉斯 记得读本科的时候，最喜欢到城里的计算机书店里面去闲逛，一逛就是好几个小时；有一次，在书店看到一本书，名叫贝叶斯方法。当时数学系的课程还没有学到概率统计。我心想，一个方法能够专门写出一本书来，肯定很牛逼。后来，我发现当初的那个朴素归纳推理成立了——这果然是个牛逼的方法。 ——题记 目录 0. 前言 1. 历史 1.1 一个例子：自然语言的二义性 1.2 贝叶斯公式 2. 拼写纠正 3. 模型比较与贝叶斯奥卡姆剃刀 3.1 再访拼写纠正 3.2 模型比较理论（Model Comparasion）与贝叶斯奥卡姆剃刀（Bayesian Occam’s Razor） 3.3 最小描述长度原则 3.4 最优贝叶斯推理 4. 无处不在的贝叶斯 4.1 中文分词 4.2 统计机器翻译 4.3 贝叶斯图像识别，Analysis by Synthesis 4.4 EM 算法与基于模型的聚类 4.5 最大似然与最小二乘 5. 朴素贝叶斯方法（又名“愚蠢者的贝叶斯（idiot’s bayes）”） 5.1 垃圾邮件过滤器 5.2 为什么朴素贝叶斯方法令人诧异地好——一个理论解释 [...]]]></description>
			<content:encoded><![CDATA[<div id="article_content">
<p align="center"><strong><span style="font-size: large;">数学之美番外篇：平凡而又神奇的贝叶斯方法</span></strong></p>
<p align="center"><span style="font-size: small;">By 刘未鹏(pongba)</span></p>
<p align="center"><span style="font-size: small;">C++的罗浮宫(</span><a href="http://blog.csdn.net/pongba"><span style="font-size: small;">http://blog.csdn.net/pongba</span></a><span style="font-size: small;">)</span></p>
<p align="center"><span style="font-size: small;">TopLanguage(</span><a title="http://groups.google.com/group/pongba" href="http://groups.google.com/group/pongba"><span style="font-size: small;">http://groups.google.com/group/pongba</span></a><span style="font-size: small;">)</span></p>
<p><span style="font-size: small;">概率论只不过是把常识用数学公式表达了出来。</span></p>
<p><span style="font-size: small;">——拉普拉斯</span></p>
<p><span style="font-size: small;">记得读本科的时候，最喜欢到城里的计算机书店里面去闲逛，一逛就是好几个小时；有一次，在书店看到一本书，名叫贝叶斯方法。当时数学系的课程还没有学到概率统计。我心想，一个方法能够专门写出一本书来，肯定很牛逼。后来，我发现当初的那个朴素归纳推理成立了——这果然是个牛逼的方法。</span></p>
<p><span style="font-size: small;">——题记</span></p>
<p><strong><span style="font-size: small;">目录</span></strong></p>
<p><span style="font-size: small;">0. 前言<br />
1. 历史<br />
1.1 一个例子：自然语言的二义性<br />
1.2 贝叶斯公式<br />
2. 拼写纠正<br />
3. 模型比较与贝叶斯奥卡姆剃刀<br />
3.1 再访拼写纠正<br />
3.2 模型比较理论（Model Comparasion）与贝叶斯奥卡姆剃刀（Bayesian Occam’s Razor）<br />
3.3 最小描述长度原则<br />
3.4 最优贝叶斯推理<br />
4. 无处不在的贝叶斯<br />
4.1 中文分词<br />
4.2 统计机器翻译<br />
4.3 贝叶斯图像识别，Analysis by Synthesis<br />
4.4 EM 算法与基于模型的聚类<br />
4.5 最大似然与最小二乘<br />
5. 朴素贝叶斯方法（又名“愚蠢者的贝叶斯（idiot’s bayes）”）<br />
5.1 垃圾邮件过滤器<br />
5.2 为什么朴素贝叶斯方法令人诧异地好——一个理论解释<br />
6. 层级贝叶斯模型<br />
6.1 隐马可夫模型（HMM）<br />
7. 贝叶斯网络</span></p>
<p><strong><span style="font-size: small;">0. 前言</span></strong></p>
<p><span style="font-size: small;">这是一篇关于贝叶斯方法的科普文，我会尽量少用公式，多用平白的语言叙述，多举实际例子。更严格的公式和计算我会在相应的地方注明参考资料。贝叶斯方法被证明是非常 general 且强大的推理框架，文中你会看到很多有趣的应用。 </span></p>
<p><strong><span style="font-size: small;">1. 历史</span></strong></p>
<p><span style="font-size: small;">托马斯·贝叶斯（Thomas Bayes）同学的详细生平在</span><a href="http://en.wikipedia.org/wiki/Thomas_Bayes" target="_blank"><span style="font-size: small;">这里</span></a><span style="font-size: small;">。以下摘一段 wikipedia 上的简介：</span></p>
<blockquote><p><span style="font-size: small;">所谓的贝叶斯方法源于他生前为解决一个“逆概”问题写的一篇文章，而这篇文章是在他死后才由他的一位朋友发表出来的。在贝叶斯写这篇文章之前，人们已经能够计算“正向概率”，如“假设袋子里面有N个白球，M个黑球，你伸手进去摸一把，摸出黑球的概率是多大”。而一个自然而然的问题是反过来：“如果我们事先并不知道袋子里面黑白球的比例，而是闭着眼睛摸出一个（或好几个）球，观察这些取出来的球的颜色之后，那么我们可以就此对袋子里面的黑白球的比例作出什么样的推测”。这个问题，就是所谓的逆概问题。</span></p></blockquote>
<p><span style="font-size: small;">实际上，贝叶斯当时的论文只是对这个问题的一个直接的求解尝试，并不清楚他当时是不是已经意识到这里面包含着的深刻的思想。然而后来，贝叶斯方法席卷了概率论，并将应用延伸到各个问题领域，所有需要作出概率预测的地方都可以见到贝叶斯方法的影子，特别地，贝叶斯是机器学习的核心方法之一。这背后的深刻原因在于，现实世界本身就是不确定的，人类的观察能力是有局限性的（否则有很大一部分科学就没有必要做了——设想我们能够直接观察到电子的运行，还需要对原子模型争吵不休吗？），我们日常所观察到的只是事物表面上的结果，沿用刚才那个袋子里面取球的比方，我们往往只能知道从里面取出来的球是什么颜色，而并不能直接看到袋子里面实际的情况。这个时候，我们就需要提供一个猜测（hypothesis，更为严格的说法是“假设”，这里用“猜测”更通俗易懂一点），所谓猜测，当然就是不确定的（很可能有好多种乃至无数种猜测都能满足目前的观测），<strong>但也绝对不是两眼一抹黑瞎蒙——具体地说，我们需要做两件事情：1. 算出各种不同猜测的可能性大小。2. 算出最靠谱的猜测是什么。第一个就是计算特定猜测的后验概率，对于连续的猜测空间则是计算猜测的概率密度函数。第二个则是所谓的模型比较，模型比较如果不考虑先验概率的话就是最大似然方法。</strong></span></p>
<p><strong><span style="font-size: small;">1.1 一个例子：自然语言的二义性</span></strong></p>
<p><span style="font-size: small;">下面举一个自然语言的不确定性的例子。当你看到这句话：</span></p>
<blockquote><p><span style="font-size: small;">The girl saw the boy with a telescope.</span></p></blockquote>
<p><span style="font-size: small;">你对这句话的含义有什么猜测？平常人肯定会说：那个女孩拿望远镜看见了那个男孩（即你对这个句子背后的实际语法结构的猜测是：The girl saw-with-a-telescope the boy ）。然而，仔细一想，你会发现这个句子完全可以解释成：那个女孩看见了那个拿着望远镜的男孩（即：The girl saw the-boy-with-a-telescope ）。那为什么平常生活中我们每个人都能够迅速地对这种二义性进行消解呢？这背后到底隐藏着什么样的思维法则？我们留到后面解释。</span></p>
<p><strong><span style="font-size: small;">1.2 贝叶斯公式</span></strong></p>
<p><span style="font-size: small;">贝叶斯公式是怎么来的？</span></p>
<p><span style="font-size: small;">我们还是使用 wikipedia 上的一个例子：</span></p>
<blockquote><p><span style="font-size: small;">一所学校里面有 60% 的男生，40% 的女生。男生总是穿长裤，女生则一半穿长裤一半穿裙子。有了这些信息之后我们可以容易地计算“随机选取一个学生，他（她）穿长裤的概率和穿裙子的概率是多大”，这个就是前面说的“正向概率”的计算。然而，假设你走在校园中，迎面走来一个穿长裤的学生（很不幸的是你高度近似，你只看得见他（她）穿的是否长裤，而无法确定他（她）的性别），你能够推断出他（她）是男生的概率是多大吗？</span></p></blockquote>
<p><span style="font-size: small;">一些认知科学的研究表明（《决策与判断》以及《</span><a href="http://www.douban.com/subject/3199621/" target="_blank"><span style="font-size: small;">Rationality for Mortals</span></a><span style="font-size: small;">》第12章：小孩也可以解决贝叶斯问题），我们对形式化的贝叶斯问题不擅长，但对于以频率形式呈现的等价问题却很擅长。在这里，我们不妨把问题重新叙述成：你在校园里面</span><a href="http://en.wikipedia.org/wiki/Random_walk" target="_blank"><span style="font-size: small;">随机游走</span></a><span style="font-size: small;">，遇到了 N 个穿长裤的人（仍然假设你无法直接观察到他们的性别），问这 N 个人里面有多少个女生多少个男生。</span></p>
<p><span style="font-size: small;">你说，这还不简单：算出学校里面有多少穿长裤的，然后在这些人里面再算出有多少女生，不就行了？</span></p>
<p><span style="font-size: small;">我们来算一算：假设学校里面人的总数是 U 个。60% 的男生都穿长裤，于是我们得到了 U * P(Boy) * P(Pants|Boy) 个穿长裤的（男生）（其中 P(Boy) 是男生的概率 = 60%，这里可以简单的理解为男生的比例；P(Pants|Boy) 是条件概率，即在 Boy 这个条件下穿长裤的概率是多大，这里是 100% ，因为所有男生都穿长裤）。40% 的女生里面又有一半（50%）是穿长裤的，于是我们又得到了 U * P(Girl) * P(Pants|Girl) 个穿长裤的（女生）。加起来一共是 U * P(Boy) * P(Pants|Boy) + U * P(Girl) * P(Pants|Girl) 个穿长裤的，其中有 U * P(Girl) * P(Pants|Girl) 个女生。两者一比就是你要求的答案。</span></p>
<p><span style="font-size: small;">下面我们把这个答案形式化一下：我们要求的是 P(Girl|Pants) （穿长裤的人里面有多少女生），我们计算的结果是 U * P(Girl) * P(Pants|Girl) / [U * P(Boy) * P(Pants|Boy) + U * P(Girl) * P(Pants|Girl)] 。容易发现这里校园内人的总数是无关的，可以消去。于是得到</span></p>
<p><strong><span style="font-size: small;">P(Girl|Pants) = P(Girl) * P(Pants|Girl) / [P(Boy) * P(Pants|Boy) + P(Girl) * P(Pants|Girl)]</span></strong></p>
<p><span style="font-size: small;">注意，如果把上式收缩起来，分母其实就是 P(Pants) ，分子其实就是 P(Pants, Girl) 。而这个比例很自然地就读作：在穿长裤的人（ P(Pants) ）里面有多少（穿长裤）的女孩（ P(Pants, Girl) ）。</span></p>
<p><span style="font-size: small;">上式中的 Pants 和 Boy/Girl 可以指代一切东西，所以其一般形式就是：</span></p>
<p><strong><span style="font-size: small;">P(B|A) = P(A|B) * P(B) / [P(A|B) * P(B) + P(A|~B) * P(~B) ]</span></strong></p>
<p><span style="font-size: small;">收缩起来就是：</span></p>
<p><strong><span style="font-size: small;">P(B|A) = P(AB) / P(A)</span></strong></p>
<p><span style="font-size: small;">其实这个就等于：</span></p>
<p><strong><span style="font-size: small;">P(B|A) * P(A) = P(AB)</span></strong></p>
<p><span style="font-size: small;">难怪拉普拉斯说<strong>概率论只是把常识用数学公式表达了出来</strong>。</span></p>
<p><span style="font-size: small;">然而，后面我们会逐渐发现，看似这么平凡的贝叶斯公式，背后却隐含着非常深刻的原理。</span></p>
<p><strong><span style="font-size: small;">2. 拼写纠正</span></strong></p>
<p><span style="font-size: small;">经典著作《人工智能：现代方法》的作者之一 Peter Norvig 曾经写过一篇介绍如何写一个拼写检查/纠正器的文章（原文在</span><a href="http://norvig.com/spell-correct.html" target="_blank"><span style="font-size: small;">这里</span></a><span style="font-size: small;">，徐宥的翻译版在</span><a href="http://blog.youxu.info/spell-correct.html" target="_blank"><span style="font-size: small;">这里</span></a><span style="font-size: small;">，这篇文章很深入浅出，强烈建议读一读），里面用到的就是贝叶斯方法，这里我们不打算复述他写的文章，而是简要地将其核心思想介绍一下。</span></p>
<p><span style="font-size: small;">首先，我们需要询问的是：“<strong>问题是什么？</strong>”</span></p>
<p><span style="font-size: small;">问题是我们看到用户输入了一个不在字典中的单词，我们需要去猜测：“这个家伙到底真正想输入的单词是什么呢？”用刚才我们形式化的语言来叙述就是，我们需要求：</span></p>
<p><strong><span style="font-size: small;">P(我们猜测他想输入的单词 | 他实际输入的单词)</span></strong></p>
<p><span style="font-size: small;">这个概率。并找出那个使得这个概率最大的猜测单词。显然，我们的猜测未必是唯一的，就像前面举的那个自然语言的歧义性的例子一样；这里，比如用户输入： thew ，那么他到底是想输入 the ，还是想输入 thaw ？到底哪个猜测可能性更大呢？幸运的是我们可以用贝叶斯公式来直接出它们各自的概率，我们不妨将我们的多个猜测记为 h1 h2 .. （ h 代表 hypothesis），它们都属于一个有限且离散的猜测空间 H （单词总共就那么多而已），将用户实际输入的单词记为 D （ D 代表 Data ，即观测数据），于是</span></p>
<p><span style="font-size: small;"><strong>P(我们的猜测1 | 他实际输入的单词)</strong> </span></p>
<p><span style="font-size: small;">可以抽象地记为：</span></p>
<p><span style="font-size: small;">P(h1 | D)</span></p>
<p><span style="font-size: small;">类似地，对于我们的猜测2，则是 P(h2 | D)。不妨统一记为：</span></p>
<p><span style="font-size: small;">P(h | D)</span></p>
<p><span style="font-size: small;">运用一次贝叶斯公式，我们得到：</span></p>
<p><strong><span style="font-size: small;">P(h | D) = P(h) * P(D | h) / P(D)</span></strong></p>
<p><span style="font-size: small;">对于不同的具体猜测 h1 h2 h3 .. ，P(D) 都是一样的，所以在比较 P(h1 | D) 和 P(h2 | D) 的时候我们可以忽略这个常数。即我们只需要知道：</span></p>
<p><span style="font-size: small;">P(h | D) ∝ P(h) * P(D | h) （注：那个符号的意思是“正比例于”，不是无穷大，注意符号右端是有一个小缺口的。）</span></p>
<p><span style="font-size: small;">这个式子的抽象含义是：对于给定观测数据，一个猜测是好是坏，取决于“这个猜测本身独立的可能性大小（先验概率，Prior ）”和“这个猜测生成我们观测到的数据的可能性大小”（似然，Likelihood ）的乘积。具体到我们的那个 thew 例子上，含义就是，用户实际是想输入 the 的可能性大小取决于 the 本身在词汇表中被使用的可能性（频繁程度）大小（先验概率）和 想打 the 却打成 thew 的可能性大小（似然）的乘积。</span></p>
<p><span style="font-size: small;">下面的事情就很简单了，对于我们猜测为可能的每个单词计算一下 P(h) * P(D | h) 这个值，然后取最大的，得到的就是最靠谱的猜测。</span></p>
<p><span style="font-size: small;"><strong>一点注记</strong>：Norvig 的拼写纠正器里面只提取了编辑距离为 2 以内的所有已知单词。这是为了避免去遍历字典中每个单词计算它们的 P(h) * P(D | h) ，但这种做法为了节省时间带来了一些误差。但话说回来难道我们人类真的回去遍历每个可能的单词来计算他们的后验概率吗？不可能。实际上，根据认知神经科学的观点，我们首先根据错误的单词做一个 bottom-up 的关联提取，提取出有可能是实际单词的那些候选单词，这个提取过程就是所谓的基于内容的提取，可以根据错误单词的一些模式片段提取出有限的一组候选，非常快地缩小的搜索空间（比如我输入 explaination ，单词里面就有充分的信息使得我们的大脑在常数时间内把可能性 narrow down 到 explanation 这个单词上，至于具体是根据哪些线索——如音节——来提取，又是如何在生物神经网络中实现这个提取机制的，目前还是一个没有弄清的领域）。然后，我们对这有限的几个猜测做一个 top-down 的预测，看看到底哪个对于观测数据（即错误单词）的预测效力最好，而如何衡量预测效率则就是用贝叶斯公式里面的那个 P(h) * P(D | h) 了——虽然我们很可能使用了</span><a href="http://www.douban.com/subject/1599035/" target="_blank"><span style="font-size: small;">一些启发法来简化计算</span></a><span style="font-size: small;">。后面我们还会提到这样的 bottom-up 的关联提取。</span></p>
<p><strong><span style="font-size: small;">3. 模型比较与奥卡姆剃刀</span></strong></p>
<p><strong><span style="font-size: small;">3.1 再访拼写纠正</span></strong></p>
<p><span style="font-size: small;">介绍了贝叶斯拼写纠正之后，接下来的一个自然而然的问题就来了：“<strong>为什么？</strong>”为什么要用贝叶斯公式？为什么贝叶斯公式在这里可以用？我们可以很容易地领会为什么贝叶斯公式用在前面介绍的那个男生女生长裤裙子的问题里是正确的。但为什么这里？</span></p>
<p><span style="font-size: small;">为了回答这个问题，一个常见的思路就是想想：<strong>非得这样吗？</strong>因为如果你想到了另一种做法并且证明了它也是靠谱的，那么将它与现在这个一比较，也许就能得出很有价值的信息。那么对于拼写纠错问题你能想到其他方案吗？</span></p>
<p><span style="font-size: small;">不管怎样，一个最常见的替代方案就是，选择离 thew 的</span><a href="http://en.wikipedia.org/wiki/Edit_distance" target="_blank"><span style="font-size: small;">编辑距离</span></a><span style="font-size: small;">最近的。然而 the 和 thaw 离 thew 的编辑距离都是 1 。这可咋办捏？你说，不慌，那还是好办。我们就看到底哪个更可能被错打为 thew 就是了。我们注意到字母 e 和字母 w 在键盘上离得很紧，无名指一抽筋就不小心多打出一个 w 来，the 就变成 thew 了。而另一方面 thaw 被错打成 thew 的可能性就相对小一点，因为 e 和 a 离得较远而且使用的指头相差一个指头（一个是中指一个是小指，不像 e 和 w 使用的指头靠在一块——神经科学的证据表明紧邻的身体设施之间容易串位）。OK，很好，因为你现在已经是在用最大似然方法了，或者直白一点，你就是在计算那个使得 P(D | h) 最大的 h 。</span></p>
<p><span style="font-size: small;">而贝叶斯方法计算的是什么？是 P(h) * P(D | h) 。多出来了一个 P(h) 。我们刚才说了，这个多出来的 P(h) 是特定猜测的先验概率。为什么要掺和进一个先验概率？刚才说的那个最大似然不是挺好么？很雄辩地指出了 the 是更靠谱的猜测。有什么问题呢？既然这样，我们就从给最大似然找茬开始吧——我们假设两者的似然程度是一样或非常相近，这样不就难以区分哪个猜测更靠谱了吗？比如用户输入tlp ，那到底是 top 还是 tip ？（这个例子不怎么好，因为 top 和 tip 的词频可能仍然是接近的，但一时想不到好的英文单词的例子，我们不妨就假设 top 比 tip 常见许多吧，这个假设并不影响问题的本质。）这个时候，当最大似然不能作出决定性的判断时，先验概率就可以插手进来给出指示——“既然你无法决定，那么我告诉你，一般来说 top 出现的程度要高许多，所以更可能他想打的是 top ”）。</span></p>
<p><span style="font-size: small;">以上只是最大似然的一个问题，即并不能提供决策的全部信息。</span></p>
<p><span style="font-size: small;">最大似然还有另一个问题：即便一个猜测与数据非常符合，也并不代表这个猜测就是更好的猜测，因为这个猜测本身的可能性也许就非常低。比如 MacKay 在《Information Theory : Inference and Learning Algorithms》里面就举了一个很好的例子：-1 3 7 11 你说是等差数列更有可能呢？还是 -X^3 / 11 + 9/11*X^2 + 23/11 每项把前项作为 X 带入后计算得到的数列？此外曲线拟合也是，平面上 N 个点总是可以用 N-1 阶多项式来完全拟合，当 N 个点近似但不精确共线的时候，用 N-1 阶多项式来拟合能够精确通过每一个点，然而用直线来做拟合/线性回归的时候却会使得某些点不能位于直线上。你说到底哪个好呢？多项式？还是直线？一般地说肯定是越低阶的多项式越靠谱（当然前提是也不能忽视“似然”P(D | h) ，明摆着一个多项式分布您愣是去拿直线拟合也是不靠谱的，这就是为什么要把它们两者乘起来考虑。），原因之一就是低阶多项式更常见，先验概率（ P(h) ）较大（原因之二则隐藏在 P(D | h) 里面），这就是为什么我们要用</span><a href="http://en.wikipedia.org/wiki/Spline_interpolation" target="_blank"><span style="font-size: small;">样条</span></a><span style="font-size: small;">来插值，而不是直接搞一个 N-1 阶多项式来通过任意 N 个点的原因。</span></p>
<p><span style="font-size: small;">以上分析当中隐含的哲学是，观测数据总是会有各种各样的误差，比如观测误差（比如你观测的时候一个 MM 经过你一不留神，手一抖就是一个误差出现了），所以如果过分去寻求能够完美解释观测数据的模型，就会落入所谓的数据</span><a href="http://en.wikipedia.org/wiki/Overfitting" target="_blank"><span style="font-size: small;">过配（overfitting）</span></a><span style="font-size: small;">的境地，一个过配的模型试图连误差（噪音）都去解释（而实际上噪音又是不需要解释的），显然就过犹不及了。所以 P(D | h) 大不代表你的 h （猜测）就是更好的 h。还要看 P(h) 是怎样的。所谓</span><a href="http://en.wikipedia.org/wiki/Occam%27s_razor" target="_blank"><span style="font-size: small;">奥卡姆剃刀</span></a><span style="font-size: small;">精神就是说：如果两个理论具有相似的解释力度，那么优先选择那个更简单的（往往也正是更平凡的，更少繁复的，更常见的）。</span></p>
<p><span style="font-size: small;">过分匹配的另一个原因在于当观测的结果并不是因为误差而显得“不精确”而是因为真实世界中对数据的结果产生贡献的因素太多太多，跟噪音不同，这些偏差是一些另外的因素集体贡献的结果，不是你的模型所能解释的——噪音那是不需要解释——一个现实的模型往往只提取出几个与结果相关度很高，很重要的因素（cause）。这个时候观察数据会倾向于围绕你的有限模型的预测结果呈</span><a href="http://en.wikipedia.org/wiki/Normal_Distribution" target="_blank"><span style="font-size: small;">正态分布</span></a><span style="font-size: small;">，于是你实际观察到的结果就是这个正态分布的</span><a href="http://en.wikipedia.org/wiki/Random_sample" target="_blank"><span style="font-size: small;">随机取样</span></a><span style="font-size: small;">，这个取样很可能受到其余因素的影响偏离你的模型所预测的中心，这个时候便不能贪心不足地试图通过改变模型来“完美”匹配数据，因为那些使结果偏离你的预测的贡献因素不是你这个有限模型里面含有的因素所能概括的，硬要打肿脸充胖子只能导致不实际的模型，举个教科书例子：身高和体重的实际关系近似于一个二阶多项式的关系，但大家都知道并不是只有身高才会对体重产生影响，物理世界影响体重的因素太多太多了，有人身材高大却瘦得跟稻草，有人却是横长竖不长。但不可否认的是总体上来说，那些特殊情况越是特殊就越是稀少，呈围绕最普遍情况（胖瘦适中）的正态分布，这个分布就保证了我们的身高——体重相关模型能够在大多数情况下做出靠谱的预测。但是——刚才说了，特例是存在的，就算不是特例，人有胖瘦，密度也有大小，所以完美符合身高——体重的某个假想的二阶多项式关系的人是不存在的，我们又不是欧几里德几何世界当中的理想多面体，所以，当我们对人群随机抽取了 N 个样本（数据点）试图对这 N 个数据点拟合出一个多项式的话就得注意，它肯定得是二阶多项式，我们要做的只是去根据数据点计算出多项式各项的参数（一个典型的方法就是最小二乘）；它肯定不是直线（我们又不是稻草），也不是三阶多项式四阶多项式.. 如果硬要完美拟合 N 个点，你可能会整出一个 N-1 阶多项式来——设想身高和体重的关系是 5 阶多项式看看？</span></p>
<p><strong><span style="font-size: small;">3.2 模型比较理论（Model Comparasion）与贝叶斯奥卡姆剃刀（Bayesian Occam’s Razor）</span></strong></p>
<p><span style="font-size: small;">实际上，模型比较就是去比较哪个模型（猜测）更可能隐藏在观察数据的背后。其基本思想前面已经用拼写纠正的例子来说明了。我们对用户实际想输入的单词的猜测就是模型，用户输错的单词就是观测数据。我们通过：</span></p>
<p><span style="font-size: small;">P(h | D) ∝ P(h) * P(D | h)</span></p>
<p><span style="font-size: small;">来比较哪个模型最为靠谱。前面提到，光靠 P(D | h) （即“似然”）是不够的，有时候还需要引入 P(h) 这个先验概率。奥卡姆剃刀就是说 P(h) 较大的模型有较大的优势，而最大似然则是说最符合观测数据的（即 P(D | h) 最大的）最有优势。整个模型比较就是这两方力量的拉锯。我们不妨再举一个简单的例子来说明这一精神：你随便找枚硬币，掷一下，观察一下结果。好，你观察到的结果要么是“正”，要么是“反”（不，不是少林足球那枚硬币:P ），不妨假设你观察到的是“正”。现在你要去根据这个观测数据推断这枚硬币掷出“正”的概率是多大。根据最大似然估计的精神，我们应该猜测这枚硬币掷出“正”的概率是 1 ，因为这个才是能最大化 P(D | h) 的那个猜测。然而每个人都会大摇其头——很显然，你随机摸出一枚硬币这枚硬币居然没有反面的概率是“不存在的”，我们对一枚随机硬币是否一枚有偏硬币，偏了多少，是有着一个先验的认识的，这个认识就是绝大多数硬币都是基本公平的，偏得越多的硬币越少见（可以用一个 </span><a href="http://en.wikipedia.org/wiki/Beta_distribution" target="_blank"><span style="font-size: small;">beta 分布</span></a><span style="font-size: small;">来表达这一先验概率）。将这个先验正态分布 p(θ) （其中 θ 表示硬币掷出正面的比例，小写的 p 代表这是</span><a href="http://en.wikipedia.org/wiki/Probability_density_function" target="_blank"><span style="font-size: small;">概率密度函数</span></a><span style="font-size: small;">）结合到我们的问题中，我们便不是去最大化 P(D | h) ，而是去最大化 P(D | θ) * p(θ) ，显然 θ = 1 是不行的，因为 P(θ=1) 为 0 ，导致整个乘积也为 0 。实际上，只要对这个式子求一个导数就可以得到最值点。</span></p>
<p><span style="font-size: small;">以上说的是当我们知道先验概率 P(h) 的时候，光用最大似然是不靠谱的，因为最大似然的猜测可能先验概率非常小。然而，有些时候，我们对于先验概率一无所知，只能假设每种猜测的先验概率是均等的，这个时候就只有用最大似然了。实际上，统计学家和贝叶斯学家有一个有趣的争论，统计学家说：我们让数据自己说话。言下之意就是要摒弃先验概率。而贝叶斯支持者则说：数据会有各种各样的偏差，而一个靠谱的先验概率则可以对这些随机噪音做到健壮。事实证明贝叶斯派胜利了，胜利的关键在于所谓先验概率其实也是经验统计的结果，譬如为什么我们会认为绝大多数硬币是基本公平的？为什么我们认为大多数人的肥胖适中？为什么我们认为肤色是种族相关的，而体重则与种族无关？先验概率里面的“先验”并不是指先于一切经验，而是仅指先于我们“当前”给出的观测数据而已，在硬币的例子中先验指的只是先于我们知道投掷的结果这个经验，而并非“先天”。</span></p>
<p><span style="font-size: small;">然而，话说回来，有时候我们必须得承认，就算是基于以往的经验，我们手头的“先验”概率还是均匀分布，这个时候就必须依赖用最大似然，我们用前面留下的一个自然语言二义性问题来说明这一点：</span></p>
<blockquote><p><span style="font-size: small;">The girl saw the boy with a telescope.</span></p></blockquote>
<p><span style="font-size: small;">到底是 The girl saw-with-a-telescope the boy 这一语法结构，还是 The girl saw the-boy-with-a-telescope 呢？两种语法结构的常见程度都差不多（你可能会觉得后一种语法结构的常见程度较低，这是事后偏见，你只需想想 The girl saw the boy with a book 就知道了。当然，实际上从大规模语料统计结果来看后一种语法结构的确稍稍不常见一丁点，但是绝对不足以解释我们对第一种结构的强烈倾向）。那么到底为什么呢？</span></p>
<p><span style="font-size: small;">我们不妨先来看看 MacKay 在书中举的一个漂亮的例子：</span></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/170505281.JPG?d=20080921170542625" alt="" /> </span></p>
<p><span style="font-size: small;">图中有多少个箱子？特别地，那棵书后面是一个箱子？还是两个箱子？还是三个箱子？还是.. 你可能会觉得树后面肯定是一个箱子，但为什么不是两个呢？如下图：</span></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/170505312.JPG?d=20080921170725125" alt="" /> </span></p>
<p><span style="font-size: small;">很简单，你会说：要是真的有两个箱子那才怪了，怎么就那么巧这两个箱子刚刚好颜色相同，高度相同呢？</span></p>
<p><span style="font-size: small;">用概率论的语言来说，你刚才的话就翻译为：猜测 h 不成立，因为 P(D | h) 太小（太巧合）了。我们的直觉是：巧合（小概率）事件不会发生。所以当一个猜测（假设）使得我们的观测结果成为小概率事件的时候，我们就说“才怪呢，哪能那么巧捏？！”</span></p>
<p><span style="font-size: small;">现在我们可以回到那个自然语言二义性的例子，并给出一个完美的解释了：如果语法结构是 The girl saw the-boy-with-a-telecope 的话，怎么那个男孩偏偏手里拿的就是望远镜——一个可以被用来 saw-with 的东东捏？这也忒小概率了吧。他咋就不会拿本书呢？拿什么都好。怎么偏偏就拿了望远镜？所以唯一的解释是，这个“巧合”背后肯定有它的必然性，这个必然性就是，如果我们将语法结构解释为 The girl saw-with-a-telescope the boy 的话，就跟数据完美吻合了——既然那个女孩是用某个东西去看这个男孩的，那么这个东西是一个望远镜就完全可以解释了（不再是小概率事件了）。</span></p>
<p><span style="font-size: small;">自然语言二义性很常见，譬如上文中的一句话：</span></p>
<blockquote><p><span style="font-size: small;">参见《决策与判断》以及《</span><a href="http://www.douban.com/subject/3199621/" target="_blank"><span style="font-size: small;">Rationality for Mortals</span></a><span style="font-size: small;">》第12章：小孩也可以解决贝叶斯问题</span></p></blockquote>
<p><span style="font-size: small;">就有二义性：到底是参见这两本书的第 12 章，还是仅仅是第二本书的第 12 章呢？如果是这两本书的第 12 章那就是咄咄怪事了，怎么恰好两本书都有第 12 章，都是讲同一个问题，更诡异的是，标题还相同呢？</span></p>
<p><span style="font-size: small;">注意，以上做的是似然估计（即只看 P(D | h) 的大小），不含先验概率。通过这两个例子，尤其是那个树后面的箱子的例子我们可以看到，似然估计里面也蕴含着奥卡姆剃刀：树后面的箱子数目越多，这个模型就越复杂。单个箱子的模型是最简单的。似然估计选择了更简单的模型。</span></p>
<p><span style="font-size: small;">这个就是所谓的<strong>贝叶斯奥卡姆剃刀（Bayesian Occam’s Razor）</strong>，因为这个剃刀工作在贝叶斯公式的似然（P(D | h) ）上，而不是模型本身（ P(h) ）的先验概率上，后者是传统的奥卡姆剃刀。关于贝叶斯奥卡姆剃刀我们再来看一个前面说到的曲线拟合的例子：如果平面上有 N 个点，近似构成一条直线，但绝不精确地位于一条直线上。这时我们既可以用直线来拟合（模型1），也可以用二阶多项式（模型2）拟合，也可以用三阶多项式（模型3），.. ，特别地，用 N-1 阶多项式便能够保证肯定能完美通过 N 个数据点。那么，这些可能的模型之中到底哪个是最靠谱的呢？前面提到，一个衡量的依据是奥卡姆剃刀：越是高阶的多项式越是繁复和不常见。然而，我们其实并不需要依赖于这个先验的奥卡姆剃刀，因为有人可能会争辩说：你怎么就能说越高阶的多项式越不常见呢？我偏偏觉得所有阶多项式都是等可能的。好吧，既然如此那我们不妨就扔掉 P(h) 项，看看 P(D | h) 能告诉我们什么。我们注意到越是高阶的多项式，它的轨迹弯曲程度越是大，到了八九阶简直就是直上直下，于是我们不仅要问：一个比如说八阶多项式在平面上随机生成的一堆 N 个点偏偏恰好近似构成一条直线的概率（即 P(D | h) ）有多大？太小太小了。反之，如果背后的模型是一条直线，那么根据该模型生成一堆近似构成直线的点的概率就大得多了。这就是贝叶斯奥卡姆剃刀。</span></p>
<p><span style="font-size: small;">这里只是提供一个关于贝叶斯奥卡姆剃刀的科普，强调直观解释，更多理论公式请参考 MacKay 的著作 《Information Theory : Inference and Learning Algorithms》第 28 章。</span></p>
<p><strong><span style="font-size: small;">3.3 最小描述长度原则</span></strong></p>
<p><span style="font-size: small;">贝叶斯模型比较理论与信息论有一个有趣的关联：</span></p>
<p><span style="font-size: small;">P(h | D) ∝ P(h) * P(D | h)</span></p>
<p><span style="font-size: small;">两边求对数，将右式的乘积变成相加：</span></p>
<p><span style="font-size: small;">ln P(h | D) ∝ ln P(h) + ln P(D | h)</span></p>
<p><span style="font-size: small;">显然，最大化 P(h | D) 也就是最大化 ln P(h | D)。而 ln P(h) + ln P(D | h) 则可以解释为模型（或者称“假设”、“猜测”）h 的编码长度加上在该模型下数据 D 的编码长度。使这个和最小的模型就是最佳模型。</span></p>
<p><span style="font-size: small;">而究竟如何定义一个模型的编码长度，以及数据在模型下的编码长度则是一个问题。更多可参考 Mitchell 的 《Machine Learning》的 6.6 节，或 Mackay 的 28.3 节）</span></p>
<p><strong><span style="font-size: small;">3.4 最优贝叶斯推理</span></strong></p>
<p><span style="font-size: small;">所谓的推理，分为两个过程，第一步是对观测数据建立一个模型。第二步则是使用这个模型来推测未知现象发生的概率。我们前面都是讲的对于观测数据给出最靠谱的那个模型。然而很多时候，虽然某个模型是所有模型里面最靠谱的，但是别的模型也并不是一点机会都没有。譬如第一个模型在观测数据下的概率是 0.5 。第二个模型是 0.4 ，第三个是 0.1 。如果我们只想知道对于观测数据哪个模型最可能，那么只要取第一个就行了，故事到此结束。然而很多时候我们建立模型是为了推测未知的事情的发生概率，这个时候，三个模型对未知的事情发生的概率都会有自己的预测，仅仅因为某一个模型概率稍大一点就只听他一个人的就太不民主了。所谓的最优贝叶斯推理就是将三个模型对于未知数据的预测结论加权平均起来（权值就是模型相应的概率）。显然，这个推理是理论上的制高点，无法再优了，因为它已经把所有可能性都考虑进去了。</span></p>
<p><span style="font-size: small;">只不过实际上我们是基本不会使用这个框架的，因为计算模型可能非常费时间，二来模型空间可能是连续的，即有无穷多个模型（这个时候需要计算模型的概率分布）。结果还是非常费时间。所以这个被看作是一个理论基准。</span></p>
<p><strong><span style="font-size: small;">4. 无处不在的贝叶斯</span></strong></p>
<p><span style="font-size: small;">以下我们再举一些实际例子来说明贝叶斯方法被运用的普遍性，这里主要集中在机器学习方面，因为我不是学经济的，否则还可以找到一堆经济学的例子。</span></p>
<p><strong><span style="font-size: small;">4.1 中文分词</span></strong></p>
<p><span style="font-size: small;">贝叶斯是机器学习的核心方法之一。比如中文分词领域就用到了贝叶斯。Google 研究员吴军在《数学之美》系列中就有一篇是介绍中文分词的，这里只介绍一下核心的思想，不做赘述，详细请参考吴军的文章（</span><a href="http://www.googlechinablog.com/2006/04/blog-post_10.html" target="_blank"><span style="font-size: small;">这里</span></a><span style="font-size: small;">）。</span></p>
<p><span style="font-size: small;">分词问题的描述为：给定一个句子（字串），如：</span></p>
<p><span style="font-size: small;">南京市长江大桥</span></p>
<p><span style="font-size: small;">如何对这个句子进行分词（词串）才是最靠谱的。例如：</span></p>
<p><span style="font-size: small;">1. 南京市/长江大桥</span></p>
<p><span style="font-size: small;">2. 南京/市长/江大桥</span></p>
<p><span style="font-size: small;">这两个分词，到底哪个更靠谱呢？</span></p>
<p><span style="font-size: small;">我们用贝叶斯公式来形式化地描述这个问题，令 X 为字串（句子），Y 为词串（一种特定的分词假设）。我们就是需要寻找使得 P(Y|X) 最大的 Y ，使用一次贝叶斯可得：</span></p>
<p><span style="font-size: small;">P(Y|X) ∝ P(Y)*P(X|Y)</span></p>
<p><span style="font-size: small;">用自然语言来说就是 这种分词方式（词串）的可能性 乘以 这个词串生成我们的句子的可能性。我们进一步容易看到：可以近似地将 P(X|Y) 看作是恒等于 1 的，因为任意假想的一种分词方式之下生成我们的句子总是精准地生成的（只需把分词之间的分界符号扔掉即可）。于是，我们就变成了去最大化 P(Y) ，也就是寻找一种分词使得这个词串（句子）的概率最大化。而如何计算一个词串：</span></p>
<p><span style="font-size: small;">W1, W2, W3, W4 ..</span></p>
<p><span style="font-size: small;">的可能性呢？我们知道，根据<a href="http://en.wikipedia.org/wiki/Joint_probability" target="_blank">联合概率</a>的公式展开：P(W1, W2, W3, W4 ..) = P(W1) * P(W2|W1) * P(W3|W2, W1) * P(W4|W1,W2,W3) * .. 于是我们可以通过一系列的条件概率（右式）的乘积来求整个联合概率。然而不幸的是随着条件数目的增加（P(Wn|Wn-1,Wn-2,..,W1) 的条件有 n-1 个），</span><a href="http://en.wikipedia.org/wiki/Curse_of_dimensionality" target="_blank"><span style="font-size: small;">数据稀疏问题</span></a><span style="font-size: small;">也会越来越严重，即便语料库再大也无法统计出一个靠谱的 P(Wn|Wn-1,Wn-2,..,W1) 来。为了缓解这个问题，计算机科学家们一如既往地使用了“天真”假设：我们假设句子中一个词的出现概率只依赖于它前面的有限的 k 个词（k 一般不超过 3，如果只依赖于前面的一个词，就是2元</span><a href="http://en.wikipedia.org/wiki/N-gram" target="_blank"><span style="font-size: small;">语言模型</span></a><span style="font-size: small;">（2-gram），同理有 3-gram 、 4-gram 等），这个就是所谓的“有限地平线”假设。虽然这个假设很傻很天真，但结果却表明它的结果往往是很好很强大的，后面要提到的朴素贝叶斯方法使用的假设跟这个精神上是完全一致的，我们会解释为什么像这样一个天真的假设能够得到强大的结果。目前我们只要知道，有了这个假设，刚才那个乘积就可以改写成： P(W1) * P(W2|W1) * P(W3|W2) * P(W4|W3) .. （假设每个词只依赖于它前面的一个词）。而统计 P(W2|W1) 就不再受到数据稀疏问题的困扰了。对于我们上面提到的例子“南京市长江大桥”，如果按照自左到右的贪婪方法分词的话，结果就成了“南京市长/江大桥”。但如果按照贝叶斯分词的话（假设使用 3-gram），由于“南京市长”和“江大桥”在语料库中一起出现的频率为 0 ，这个整句的概率便会被判定为 0 。 从而使得“南京市/长江大桥”这一分词方式胜出。</span></p>
<p><span style="font-size: small;"><strong>一点注记</strong>：有人可能会疑惑，难道我们人类也是基于这些天真的假设来进行推理的？不是的。事实上，统计机器学习方法所统计的东西往往处于相当表层（shallow）的层面，在这个层面机器学习只能看到一些非常表面的现象，有一点科学研究的理念的人都知道：越是往表层去，世界就越是繁复多变。从机器学习的角度来说，特征（feature）就越多，成百上千维度都是可能的。特征一多，好了，</span><a href="http://en.wikipedia.org/wiki/Curse_of_dimensionality" target="_blank"><span style="font-size: small;">高维诅咒</span></a><span style="font-size: small;">就产生了，数据就稀疏得要命，不够用了。而我们人类的观察水平显然比机器学习的观察水平要更深入一些，为了避免数据稀疏我们不断地发明各种装置（最典型就是显微镜），来帮助我们直接深入到更深层的事物层面去观察更本质的联系，而不是在浅层对表面现象作统计归纳。举一个简单的例子，通过对大规模语料库的统计，机器学习可能会发现这样一个规律：所有的“他”都是不会穿 bra 的，所有的“她”则都是穿的。然而，作为一个男人，却完全无需进行任何统计学习，因为深层的规律就决定了我们根本不会去穿 bra 。至于机器学习能不能完成后者（像人类那样的）这个推理，则是人工智能领域的经典问题。至少在那之前，</span><a href="http://www.yeeyan.com/articles/view/sylviaangel/9995" target="_blank"><span style="font-size: small;">声称统计学习方法能够终结科学研究</span></a><span style="font-size: small;">（</span><a href="http://www.wired.com/science/discoveries/magazine/16-07/pb_theory" target="_blank"><span style="font-size: small;">原文</span></a><span style="font-size: small;">）的说法</span><a href="http://scienceblogs.com/goodmath/2008/07/petabyte_scale_dataanalysis_an.php" target="_blank"><span style="font-size: small;">是纯粹外行人说的话</span></a><span style="font-size: small;">。</span></p>
<p><strong><span style="font-size: small;">4.2 统计机器翻译</span></strong></p>
<p><span style="font-size: small;">统计机器翻译因为其简单，自动（无需手动添加规则），迅速成为了机器翻译的事实标准。而统计机器翻译的核心算法也是使用的贝叶斯方法。</span></p>
<p><span style="font-size: small;">问题是什么？统计机器翻译的问题可以描述为：给定一个句子 e ，它的可能的外文翻译 f 中哪个是最靠谱的。即我们需要计算：P(f|e) 。一旦出现条件概率贝叶斯总是挺身而出：</span></p>
<p><span style="font-size: small;">P(f|e) ∝ P(f) * P(e|f)</span></p>
<p><span style="font-size: small;">这个式子的右端很容易解释：那些先验概率较高，并且更可能生成句子 e 的外文句子 f 将会胜出。我们只需简单统计（结合上面提到的 N-Gram 语言模型）就可以统计任意一个外文句子 f 的出现概率。然而 P(e|f) 却不是那么好求的，给定一个候选的外文局子 f ，它生成（或对应）句子 e 的概率是多大呢？我们需要定义什么叫 “对应”，这里需要用到一个分词对齐的平行语料库，有兴趣的可以参考 《Foundations of Statistical Natural Language Processing》第 13 章，这里摘选其中的一个例子：假设 e 为：John loves Mary 。我们需要考察的首选 f 是：Jean aime Marie （法文）。我们需要求出 P(e|f) 是多大，为此我们考虑 e 和 f 有多少种对齐的可能性，如：</span></p>
<p><span style="font-size: small;">John (Jean) loves (aime) Marie (Mary) </span></p>
<p><span style="font-size: small;">就是其中的一种（最靠谱的）对齐，为什么要对齐，是因为一旦对齐了之后，就可以容易地计算在这个对齐之下的 P(e|f) 是多大，只需计算：</span></p>
<p><span style="font-size: small;">P(John|Jean) * P(loves|aime) * P(Marie|Mary)</span></p>
<p><span style="font-size: small;">即可。</span></p>
<p><span style="font-size: small;">然后我们遍历所有的对齐方式，并将每种对齐方式之下的翻译概率 ∑ 求和。便可以获得整个的 P(e|f) 是多大。</span></p>
<p><span style="font-size: small;"><strong>一点注记</strong>：还是那个问题：难道我们人类真的是用这种方式进行翻译的？highly unlikely 。这种计算复杂性非常高的东西连三位数乘法都搞不定的我们才不会笨到去使用呢。根据认知神经科学的认识，很可能我们是先从句子到语义（一个逐层往上（bottom-up）抽象的 folding 过程），然后从语义根据另一门语言的语法展开为另一门语言（一个逐层往下（top-down）的具体化 unfolding 过程）。如何可计算地实现这个过程，目前仍然是个难题。（我们看到很多地方都有 bottom-up/top-down 这样一个对称的过程，实际上有人猜测这正是生物神经网络原则上的运作方式，对视觉神经系统的研究尤其证明了这一点，Hawkins 在 《On Intelligence》 里面提出了一种 <a href="http://en.wikipedia.org/wiki/Hierarchical_Temporal_Memory" target="_blank">HTM</a> （Hierarchical Temporal Memory）模型正是使用了这个原则。）</span></p>
<p><strong><span style="font-size: small;">4.3 贝叶斯图像识别，Analysis by Synthesis</span></strong></p>
<p><span style="font-size: small;">贝叶斯方法是一个非常 general 的推理框架。其核心理念可以描述成：Analysis by Synthesis （通过合成来分析）。06 年的认知科学新进展上有一篇 paper 就是讲用贝叶斯推理来解释视觉识别的，一图胜千言，下图就是摘自这篇 paper ：</span></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/170505343.JPG?d=20080921170815343" alt="" /> </span></p>
<p><span style="font-size: small;">首先是视觉系统提取图形的边角特征，然后使用这些特征自底向上地激活高层的抽象概念（比如是 E 还是 F 还是等号），然后使用一个自顶向下的验证来比较到底哪个概念最佳地解释了观察到的图像。</span></p>
<p><strong><span style="font-size: small;">4.4  EM 算法与基于模型的聚类</span></strong></p>
<p><a href="http://en.wikipedia.org/wiki/Data_clustering" target="_blank"><span style="font-size: small;">聚类</span></a><span style="font-size: small;">是一种</span><a href="http://en.wikipedia.org/wiki/Unsupervised_learning" target="_blank"><span style="font-size: small;">无指导的机器学习</span></a><span style="font-size: small;">问题，问题描述：给你一堆数据点，让你将它们最靠谱地分成一堆一堆的。聚类算法很多，不同的算法适应于不同的问题，这里仅介绍一个基于模型的聚类，该聚类算法对数据点的假设是，这些数据点分别是围绕 K 个核心的 K 个正态分布源所随机生成的，使用 Han JiaWei 的《Data Ming： Concepts and Techniques》中的图：</span></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/170505421.jpg?d=20080921170845484" alt="" /> </span></p>
<p><span style="font-size: small;">图中有两个正态分布核心，生成了大致两堆点。我们的聚类算法就是需要根据给出来的那些点，算出这两个正态分布的核心在什么位置，以及分布的参数是多少。这很明显又是一个贝叶斯问题，但这次不同的是，答案是连续的且有无穷多种可能性，更糟的是，只有当我们知道了哪些点属于同一个正态分布圈的时候才能够对这个分布的参数作出靠谱的预测，现在两堆点混在一块我们又不知道哪些点属于第一个正态分布，哪些属于第二个。反过来，只有当我们对分布的参数作出了靠谱的预测时候，才能知道到底哪些点属于第一个分布，那些点属于第二个分布。这就成了一个先有鸡还是先有蛋的问题了。为了解决这个循环依赖，总有一方要先打破僵局，说，不管了，我先随便整一个值出来，看你怎么变，然后我再根据你的变化调整我的变化，然后如此迭代着不断互相推导，最终收敛到一个解。这就是 EM 算法。</span></p>
<p><span style="font-size: small;">EM 的意思是“Expectation-Maximazation”，在这个聚类问题里面，我们是先随便猜一下这两个正态分布的参数：如核心在什么地方，方差是多少。然后计算出每个数据点更可能属于第一个还是第二个正态分布圈，这个是属于 Expectation 一步。有了每个数据点的归属，我们就可以根据属于第一个分布的数据点来重新评估第一个分布的参数（从蛋再回到鸡），这个是 Maximazation 。如此往复，直到参数基本不再发生变化为止。这个迭代收敛过程中的贝叶斯方法在第二步，根据数据点求分布的参数上面。</span></p>
<p><strong><span style="font-size: small;">4.5 最大似然与最小二乘</span></strong></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/171446062.png?d=20080921171606078" alt="" /> </span></p>
<p><span style="font-size: small;">学过线性代数的大概都知道经典的最小二乘方法来做线性回归。问题描述是：给定平面上 N 个点，（这里不妨假设我们想用一条直线来拟合这些点——<a href="http://en.wikipedia.org/wiki/Regression_analysis" target="_blank">回归</a>可以看作是<a href="http://en.wikipedia.org/wiki/Curve_fitting" target="_blank">拟合</a>的特例，即允许误差的拟合），找出一条最佳描述了这些点的直线。</span></p>
<p><span style="font-size: small;">一个接踵而来的问题就是，我们如何定义最佳？我们设每个点的坐标为 (Xi, Yi) 。如果直线为 y = f(x) 。那么 (Xi, Yi) 跟直线对这个点的“预测”：(Xi, f(Xi)) 就相差了一个 ΔYi = |Yi – f(Xi)| 。最小二乘就是说寻找直线使得 (ΔY1)^2 + (ΔY2)^2 + .. （即误差的平方和）最小，至于为什么是误差的平方和而不是误差的绝对值和，统计学上也没有什么好的解释。然而贝叶斯方法却能对此提供一个完美的解释。</span></p>
<p><span style="font-size: small;">我们假设直线对于坐标 Xi 给出的预测 f(Xi) 是最靠谱的预测，所有纵坐标偏离 f(Xi) 的那些数据点都含有噪音，是噪音使得它们偏离了完美的一条直线，一个合理的假设就是偏离路线越远的概率越小，具体小多少，可以用一个正态分布曲线来模拟，这个分布曲线以直线对 Xi 给出的预测 f(Xi) 为中心，实际纵坐标为 Yi 的点 (Xi, Yi) 发生的概率就正比于 EXP[-(ΔYi)^2]。（EXP(..) 代表以常数 e 为底的多少次方）。</span></p>
<p><span style="font-size: small;">现在我们回到问题的贝叶斯方面，我们要想最大化的后验概率是：</span></p>
<p><span style="font-size: small;">P(h|D) ∝ P(h) * P(D|h)</span></p>
<p><span style="font-size: small;">又见贝叶斯！这里 h 就是指一条特定的直线，D 就是指这 N 个数据点。我们需要寻找一条直线 h 使得 P(h) * P(D|h) 最大。很显然，P(h) 这个先验概率是均匀的，因为哪条直线也不比另一条更优越。所以我们只需要看 P(D|h) 这一项，这一项是指这条直线生成这些数据点的概率，刚才说过了，生成数据点 (Xi, Yi) 的概率为 EXP[-(ΔYi)^2] 乘以一个常数。而 P(D|h) = P(d1|h) * P(d2|h) * .. 即假设各个数据点是独立生成的，所以可以把每个概率乘起来。于是生成 N 个数据点的概率为 EXP[-(ΔY1)^2] * EXP[-(ΔY2)^2] * EXP[-(ΔY3)^2] * .. = EXP<strong>{-[(ΔY1)^2 + (ΔY2)^2 + (ΔY3)^2 + ..</strong>]} 最大化这个概率就是要最小化 (ΔY1)^2 + (ΔY2)^2 + (ΔY3)^2 + .. 。 熟悉这个式子吗？</span></p>
<p><strong><span style="font-size: small;">5. 朴素贝叶斯方法</span></strong></p>
<p><span style="font-size: small;">朴素贝叶斯方法是一个很特别的方法，所以值得介绍一下。我们用朴素贝叶斯在垃圾邮件过滤中的应用来举例说明。</span></p>
<p><span style="font-size: small;"><strong>5.1 贝叶斯垃圾邮件过滤器</strong></span></p>
<p><span style="font-size: small;">问题是什么？问题是，给定一封邮件，判定它是否属于垃圾邮件。按照先例，我们还是用 D 来表示这封邮件，注意 D 由 N 个单词组成。我们用 h+ 来表示垃圾邮件，h- 表示正常邮件。问题可以形式化地描述为求：</span></p>
<p><span style="font-size: small;">P(h+|D) = P(h+) * P(D|h+) / P(D)</span></p>
<p><span style="font-size: small;">P(h-|D) = P(h-) * P(D|h-) / P(D)</span></p>
<p><span style="font-size: small;">其中 P(h+) 和 P(h-) 这两个先验概率都是很容易求出来的，只需要计算一个邮件库里面垃圾邮件和正常邮件的比例就行了。然而 P(D|h+) 却不容易求，因为 D 里面含有 N 个单词 d1, d2, d3, .. ，所以P(D|h+) = P(d1,d2,..,dn|h+) 。我们又一次遇到了数据稀疏性，为什么这么说呢？P(d1,d2,..,dn|h+) 就是说在垃圾邮件当中出现跟我们目前这封邮件一模一样的一封邮件的概率是多大！开玩笑，每封邮件都是不同的，世界上有无穷多封邮件。瞧，这就是数据稀疏性，因为可以肯定地说，你收集的训练数据库不管里面含了多少封邮件，也不可能找出一封跟目前这封一模一样的。结果呢？我们又该如何来计算 P(d1,d2,..,dn|h+) 呢？</span></p>
<p><span style="font-size: small;">我们将 P(d1,d2,..,dn|h+)  扩展为： P(d1|h+) * P(d2|d1, h+) * P(d3|d2,d1, h+) * .. 。熟悉这个式子吗？这里我们会使用一个更激进的假设，我们假设 di 与 di-1 是完全条件无关的，于是式子就简化为 P(d1|h+) * P(d2|h+) * P(d3|h+) * .. 。这个就是所谓的</span><a href="http://en.wikipedia.org/wiki/Conditional_independence" target="_blank"><span style="font-size: small;">条件独立假设</span></a><span style="font-size: small;">，也正是朴素贝叶斯方法的朴素之处。而计算 P(d1|h+) * P(d2|h+) * P(d3|h+) * .. 就太简单了，只要统计 di 这个单词在垃圾邮件中出现的频率即可。关于贝叶斯垃圾邮件过滤更多的内容可以参考</span><a href="http://en.wikipedia.org/wiki/Bayesian_spam_filtering" target="_blank"><span style="font-size: small;">这个条目</span></a><span style="font-size: small;">，注意其中提到的其他资料。</span></p>
<p><span style="font-size: small;"><strong>一点注记</strong>：这里，为什么有这个数据稀疏问题，还是因为统计学习方法工作在浅层面， 世界上的单词就算不再变多也是非常之多的，单词之间组成的句子也是变化多端，更不用说一篇文章了，文章数目则是无穷的，所以在这个层面作统计，肯定要被数据稀疏性困扰。我们要注意，虽然句子和文章的数目是无限的，然而就拿邮件来说，如果我们只关心邮件中句子的语义（进而更高抽象层面的“意图”（语义，意图如何可计算地定义出来是一个人工智能问题），在这个层面上可能性便大大缩减了，我们关心的抽象层面越高，可能性越小。单词集合和句子的对应是多对一的，句子和语义的对应又是多对一的，语义和意图的对应还是多对一的，这是个层级体系。神经科学的发现也表明大脑的皮层大致有一种层级结构，对应着越来越抽象的各个层面，至于如何具体实现一个可放在计算机内的大脑皮层，仍然是一个未解决问题，以上只是一个原则（principle）上的认识，只有当 computational 的 cortex 模型被建立起来了之后才可能将其放入电脑。</span></p>
<p><span style="font-size: small;"><strong>5.2 为什么朴素贝叶斯方法令人诧异地好——一个理论解释</strong></span></p>
<p><span style="font-size: small;">朴素贝叶斯方法的条件独立假设看上去很傻很天真，为什么结果却很好很强大呢？就拿一个句子来说，我们怎么能鲁莽地声称其中任意一个单词出现的概率只受到它前面的 3 个或 4 个单词的影响呢？别说 3 个，有时候一个单词的概率受到上一句话的影响都是绝对可能的。那么为什么这个假设在实际中的表现却不比决策树差呢？有人对此提出了一个理论解释，并且建立了什么时候朴素贝叶斯的效果能够等价于非朴素贝叶斯的充要条件，这个解释的核心就是：有些独立假设在各个分类之间的分布都是均匀的所以对于似然的相对大小不产生影响；即便不是如此，也有很大的可能性各个独立假设所产生的消极影响或积极影响互相抵消，最终导致结果受到的影响不大。具体的数学公式请参考</span><a href="http://www.cs.unb.ca/profs/hzhang/publications/FLAIRS04ZhangH.pdf" target="_blank"><span style="font-size: small;">这篇 paper</span></a><span style="font-size: small;"> 。</span></p>
<p><strong><span style="font-size: small;">6. 层级贝叶斯模型</span></strong></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/171446421.PNG?d=20080921171532953" alt="" /> </span></p>
<p><a href="http://en.wikipedia.org/wiki/Hierarchical_Bayes_model" target="_blank"><span style="font-size: small;">层级贝叶斯模型</span></a><span style="font-size: small;">是现代贝叶斯方法的标志性建筑之一。前面讲的贝叶斯，都是在同一个事物层次上的各个因素之间进行统计推理，然而层次贝叶斯模型在哲学上更深入了一层，将这些因素背后的因素（原因的原因，原因的原因，以此类推）囊括进来。一个教科书例子是：如果你手头有 N 枚硬币，它们是同一个工厂铸出来的，你把每一枚硬币掷出一个结果，然后基于这 N 个结果对这 N 个硬币的 θ （出现正面的比例）进行推理。如果根据最大似然，每个硬币的 θ 不是 1 就是 0 （这个前面提到过的），然而我们又知道每个硬币的 p(θ) 是有一个先验概率的，也许是一个 beta 分布。也就是说，每个硬币的实际投掷结果 Xi 服从以 θ 为中心的正态分布，而 θ 又服从另一个以 Ψ 为中心的 beta 分布。层层因果关系就体现出来了。进而 Ψ 还可能依赖于因果链上更上层的因素，以此类推。</span></p>
<p><strong><span style="font-size: small;">6.1 隐马可夫模型（HMM）</span></strong></p>
<p><span style="font-size: small;"><img src="http://album.hi.csdn.net/App_Uploads/pongba/20080921/171446093.png?d=20080921171454734" alt="" /> </span></p>
<p><span style="font-size: small;">吴军在数学之美系列里面介绍的</span><a href="http://en.wikipedia.org/wiki/Hidden_Markov_model" target="_blank"><span style="font-size: small;">隐马可夫模型</span></a><span style="font-size: small;">（HMM）就是一个简单的层级贝叶斯模型：</span></p>
<blockquote><p><span style="font-size: small;">那么怎么根据接收到的信息来推测说话者想表达的意思呢？我们可以利用叫做“隐含马尔可夫模型”（Hidden Markov Model）来解决这些问题。以语音识别为例，当我们观测到语音信号 o1,o2,o3 时，我们要根据这组信号推测出发送的句子 s1,s2,s3。显然，我们应该在所有可能的句子中找最有可能性的一个。用数学语言来描述，就是在已知 o1,o2,o3,...的情况下，求使得条件概率 P (s1,s2,s3,...|o1,o2,o3....) 达到最大值的那个句子 s1,s2,s3,...</span></p></blockquote>
<p><span style="font-size: small;">吴军的文章中这里省掉没说的是，s1, s2, s3, .. 这个句子的生成概率同时又取决于一组参数，这组参数决定了 s1, s2, s3, .. 这个马可夫链的先验生成概率。如果我们将这组参数记为 λ ，我们实际上要求的是：P(S|O, λ) （其中 O 表示 o1,o2,o3,.. ，S表示 s1,s2,s3,..）</span></p>
<blockquote><p><span style="font-size: small;">当然，上面的概率不容易直接求出，于是我们可以间接地计算它。利用贝叶斯公式并且省掉一个常数项，可以把上述公式等价变换成</span></p>
<p><span style="font-size: small;">P(o1,o2,o3,...|s1,s2,s3....) * P(s1,s2,s3,...)</span></p>
<p><span style="font-size: small;">其中</span></p>
<p><span style="font-size: small;">P(o1,o2,o3,...|s1,s2,s3....) 表示某句话 s1,s2,s3...被读成 o1,o2,o3,...的可能性, 而 P(s1,s2,s3,...) 表示字串 s1,s2,s3,...本身能够成为一个合乎情理的句子的可能性，所以这个公式的意义是用发送信号为 s1,s2,s3...这个数列的可能性乘以 s1,s2,s3.. 本身可以一个句子的可能性，得出概率。</span></p></blockquote>
<p><span style="font-size: small;">这里，s1,s2,s3...本身可以一个句子的可能性其实就取决于参数 λ ，也就是语言模型。所以简而言之就是发出的语音信号取决于背后实际想发出的句子，而背后实际想发出的句子本身的独立先验概率又取决于语言模型。</span></p>
<p><strong><span style="font-size: small;">7. 贝叶斯网络</span></strong></p>
<p><span style="font-size: small;">吴军已经对贝叶斯网络作了科普，请直接跳转到</span><a href="http://googlechinablog.com/2007/01/bayesian-networks.html" target="_blank"><span style="font-size: small;">这里</span></a><span style="font-size: small;">。更详细的理论参考所有机器学习的书上都有。</span></p>
<p><span style="font-size: small;">参考资料：</span></p>
<p><span style="font-size: small;">一堆机器学习，一堆概率统计，一堆 Google ，和一堆 Wikipedia 条目，一堆 paper 。</span></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/%e6%95%b0%e5%ad%a6%e4%b9%8b%e7%be%8e%e7%95%aa%e5%a4%96%e7%af%87%ef%bc%9a%e5%b9%b3%e5%87%a1%e8%80%8c%e5%8f%88%e7%a5%9e%e5%a5%87%e7%9a%84%e8%b4%9d%e5%8f%b6%e6%96%af%e6%96%b9%e6%b3%95%e8%bd%ac.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2012恭贺新春：腊梅花开</title>
		<link>http://www.buguw.com/2012%e6%81%ad%e8%b4%ba%e6%96%b0%e6%98%a5%ef%bc%9a%e8%85%8a%e6%a2%85%e8%8a%b1%e5%bc%80.html</link>
		<comments>http://www.buguw.com/2012%e6%81%ad%e8%b4%ba%e6%96%b0%e6%98%a5%ef%bc%9a%e8%85%8a%e6%a2%85%e8%8a%b1%e5%bc%80.html#comments</comments>
		<pubDate>Thu, 29 Dec 2011 03:51:26 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[闲言碎语]]></category>
		<category><![CDATA[元旦]]></category>
		<category><![CDATA[腊梅]]></category>

		<guid isPermaLink="false">http://www.buguw.com/?p=249</guid>
		<description><![CDATA[点击打开：送你祝福 感谢所有朋友的支持与关注！在节日前夕，送上一枝枝傲雪寒梅，祝您的新一年里：身体健康，生活幸福，心情愉快，事业高升！祝您元旦快乐-------您就随着心情使劲的点.使劲的乐吧！]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;"><span style="color: #ff0000;"><strong><a href="http://www.buguw.com/wp-content/uploads/2011/12/送你祝福.swf"><span style="color: #ff0000;">点击打开：送你祝福</span></a></strong></span></h1>
<p style="text-align: center;"><a href="http://www.buguw.com/wp-content/uploads/2011/12/送你祝福.swf"><img class="aligncenter  wp-image-257" title="28" src="http://www.buguw.com/wp-content/uploads/2011/12/28-300x182.jpg" alt="" width="300" height="182" /></a></p>
<p><span style="color: #ff0000;">感谢所有朋友的支持与关注！在节日前夕，送上一枝枝傲雪寒梅，祝您的新一年里：身体健康，生活幸福，心情愉快，事业高升！祝您元旦快乐-------您就随着心情使劲的点.使劲的乐吧！</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/2012%e6%81%ad%e8%b4%ba%e6%96%b0%e6%98%a5%ef%bc%9a%e8%85%8a%e6%a2%85%e8%8a%b1%e5%bc%80.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VS2010&quot;为帮助内容存储区指定的位置无效或者您无权访问该位置&quot;解决方法</title>
		<link>http://www.buguw.com/vs2010%e4%b8%ba%e5%b8%ae%e5%8a%a9%e5%86%85%e5%ae%b9%e5%ad%98%e5%82%a8%e5%8c%ba%e6%8c%87%e5%ae%9a%e7%9a%84%e4%bd%8d%e7%bd%ae%e6%97%a0%e6%95%88%e6%88%96%e8%80%85%e6%82%a8%e6%97%a0%e6%9d%83.html</link>
		<comments>http://www.buguw.com/vs2010%e4%b8%ba%e5%b8%ae%e5%8a%a9%e5%86%85%e5%ae%b9%e5%ad%98%e5%82%a8%e5%8c%ba%e6%8c%87%e5%ae%9a%e7%9a%84%e4%bd%8d%e7%bd%ae%e6%97%a0%e6%95%88%e6%88%96%e8%80%85%e6%82%a8%e6%97%a0%e6%9d%83.html#comments</comments>
		<pubDate>Mon, 31 Oct 2011 13:05:43 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[程序人生]]></category>
		<category><![CDATA[vs2010]]></category>

		<guid isPermaLink="false">http://www.buguw.com/vs2010%e4%b8%ba%e5%b8%ae%e5%8a%a9%e5%86%85%e5%ae%b9%e5%ad%98%e5%82%a8%e5%8c%ba%e6%8c%87%e5%ae%9a%e7%9a%84%e4%bd%8d%e7%bd%ae%e6%97%a0%e6%95%88%e6%88%96%e8%80%85%e6%82%a8%e6%97%a0%e6%9d%83.html</guid>
		<description><![CDATA[&#160;&#160;&#160; 突然发现vs2010的msdn帮助全没了，打开帮助设置，提示:&#34;为帮助内容存储区指定的位置无效或者您无权访问该位置&#34;，要了亲命了，以前可是花了无数时间在线更新到最新状态滴！ 百度了一下，找到了解决办法: 打开注册表，定位到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help，删除help下的子项。重启vs，打开帮助设置，重新指定本地msdn帮助的目录为“以前安装的msdn帮助目录&#34;]]></description>
			<content:encoded><![CDATA[<p>&#160;&#160;&#160; 突然发现vs2010的msdn帮助全没了，打开帮助设置，提示:&quot;为帮助内容存储区指定的位置无效或者您无权访问该位置&quot;，要了亲命了，以前可是花了无数时间在线更新到最新状态滴！</p>
<p>百度了一下，找到了解决办法:   <br />打开注册表，定位到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help，删除help下的子项。重启vs，打开帮助设置，重新指定本地msdn帮助的目录为“以前安装的msdn帮助目录&quot;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/vs2010%e4%b8%ba%e5%b8%ae%e5%8a%a9%e5%86%85%e5%ae%b9%e5%ad%98%e5%82%a8%e5%8c%ba%e6%8c%87%e5%ae%9a%e7%9a%84%e4%bd%8d%e7%bd%ae%e6%97%a0%e6%95%88%e6%88%96%e8%80%85%e6%82%a8%e6%97%a0%e6%9d%83.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio 遇到了异常,这可能是由某个扩展导致的~~</title>
		<link>http://www.buguw.com/visual-studio-%e9%81%87%e5%88%b0%e4%ba%86%e5%bc%82%e5%b8%b8%e8%bf%99%e5%8f%af%e8%83%bd%e6%98%af%e7%94%b1%e6%9f%90%e4%b8%aa%e6%89%a9%e5%b1%95%e5%af%bc%e8%87%b4%e7%9a%84.html</link>
		<comments>http://www.buguw.com/visual-studio-%e9%81%87%e5%88%b0%e4%ba%86%e5%bc%82%e5%b8%b8%e8%bf%99%e5%8f%af%e8%83%bd%e6%98%af%e7%94%b1%e6%9f%90%e4%b8%aa%e6%89%a9%e5%b1%95%e5%af%bc%e8%87%b4%e7%9a%84.html#comments</comments>
		<pubDate>Tue, 19 Apr 2011 04:56:03 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[编程学习经验]]></category>
		<category><![CDATA[VS2010，异常]]></category>
		<category><![CDATA[扩展]]></category>

		<guid isPermaLink="false">http://www.buguw.com/visual-studio-%e9%81%87%e5%88%b0%e4%ba%86%e5%bc%82%e5%b8%b8%e8%bf%99%e5%8f%af%e8%83%bd%e6%98%af%e7%94%b1%e6%9f%90%e4%b8%aa%e6%89%a9%e5%b1%95%e5%af%bc%e8%87%b4%e7%9a%84.html</guid>
		<description><![CDATA[作者：ThelostMind 装了个VS2010，安装了2008的MSDN，结果问题就出现了: 只要在VS2010源码编辑器中输入一个字符，它就报道错误了 &#34;visual studio 2010 遇到了异常,可能是由某个扩展导致的......&#34;。刚开始一看，以为是扩展引起的，那我就把vs中所有的扩展暂时禁用一下，结果bug还是依旧。求助google， 以下是具体的解决方法： 执行一下附件里面的注册表修复即可： 附件下载]]></description>
			<content:encoded><![CDATA[<p>作者：ThelostMind</p>
<p>装了个VS2010，安装了2008的MSDN，结果问题就出现了:</p>
<p>只要在VS2010源码编辑器中输入一个字符，它就报道错误了 &quot;visual studio 2010 遇到了异常,可能是由某个扩展导致的......&quot;。刚开始一看，以为是扩展引起的，那我就把vs中所有的扩展暂时禁用一下，结果bug还是依旧。求助google， 以下是具体的解决方法：</p>
<p>执行一下附件里面的注册表修复即可：</p>
<p><a href="http://download.csdn.net/source/3205111" target="_blank"><font color="#ff0000"><strong>附件下载</strong></font></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/visual-studio-%e9%81%87%e5%88%b0%e4%ba%86%e5%bc%82%e5%b8%b8%e8%bf%99%e5%8f%af%e8%83%bd%e6%98%af%e7%94%b1%e6%9f%90%e4%b8%aa%e6%89%a9%e5%b1%95%e5%af%bc%e8%87%b4%e7%9a%84.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;VC 2010 项目过大&#8221; 问题解决方案</title>
		<link>http://www.buguw.com/vc-2010-%e9%a1%b9%e7%9b%ae%e8%bf%87%e5%a4%a7-%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88.html</link>
		<comments>http://www.buguw.com/vc-2010-%e9%a1%b9%e7%9b%ae%e8%bf%87%e5%a4%a7-%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88.html#comments</comments>
		<pubDate>Thu, 14 Apr 2011 06:27:56 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[编程学习经验]]></category>
		<category><![CDATA[vs2010]]></category>

		<guid isPermaLink="false">http://www.buguw.com/vc-2010-%e9%a1%b9%e7%9b%ae%e8%bf%87%e5%a4%a7-%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88.html</guid>
		<description><![CDATA[使用VC2010建立C++解决方案时，会生成SolutionName.sdf和一个叫做ipch的文件夹，这两个文件再加上*.pch等文件使得工程变得非常的庞大，一个简单的程序都会占用几十M的硬盘容量，一个MFC程序甚至会占用百兆了，不去考虑硬盘容量，如果想发布自己的代码，对于无法清理的VC2010项目来说，还真是件难事。 方案一：Tools-&#62;Options-&#62;Text Editor-&#62;C/C++-&#62;Advanced-&#62;Disable Database，设置为True，即禁用数据库，这种方法实行后，还真是产生了些问题，比如，无法自动加载代码。为此，就没有使用此方法。 方案二：Tools-&#62;Options-&#62;Text Editor-&#62;C/C++-&#62;Advanced，在 Fallback Location 的属性组中，将&#34;Always Use Fallback Location&#34;设置为 true，将&#34;Do Not Warn If Fallback Location Used&#34; 设置为 true ，然后删除解决方案目录下的 sdf 文件和 ipch 目录，再次打开解决方案，发现这些烦人的东西已经不见了。中文版得为，在高级里，“退回位置”两个选项都变为True。 这样一来，几百兆的项目，用清理工具一清理，也能变成几百K了。 那么那些文件放置到那里了呢？看 &#34;Fallback Location&#34; 属性说明：这是存储浏览信息数据库和 IntelliSense 文件的第二个位置，如果不指定则放置到临时目录中；到临时目录一看，里面有一个 VC++ 的目录，都在那个目录里面呢。 可以在 &#34;Fallback Location&#34; 属性中，设置一个固定的路径来存储这些文件，比如D:\VS2010Temp，这样也比较好管理这些庞大的臃肿的文件，可以定期清理掉它们，释放出硬盘空间！ 原文出处：http://www.cnblogs.com/rogee/archive/2010/10/30/1865062.html]]></description>
			<content:encoded><![CDATA[<p>使用VC2010建立C++解决方案时，会生成SolutionName.sdf和一个叫做ipch的文件夹，这两个文件再加上*.pch等文件使得工程变得非常的庞大，一个简单的程序都会占用几十M的硬盘容量，一个MFC程序甚至会占用百兆了，不去考虑硬盘容量，如果想发布自己的代码，对于无法清理的VC2010项目来说，还真是件难事。   <br />方案一：Tools-&gt;Options-&gt;Text Editor-&gt;C/C++-&gt;Advanced-&gt;Disable Database，设置为True，即禁用数据库，这种方法实行后，还真是产生了些问题，比如，无法自动加载代码。为此，就没有使用此方法。    <br />方案二：Tools-&gt;Options-&gt;Text Editor-&gt;C/C++-&gt;Advanced，在 Fallback Location 的属性组中，将&quot;Always Use Fallback Location&quot;设置为 true，将&quot;Do Not Warn If Fallback Location Used&quot; 设置为 true ，然后删除解决方案目录下的 sdf 文件和 ipch 目录，再次打开解决方案，发现这些烦人的东西已经不见了。中文版得为，在高级里，“退回位置”两个选项都变为True。    <br />这样一来，几百兆的项目，用清理工具一清理，也能变成几百K了。    <br />那么那些文件放置到那里了呢？看 &quot;Fallback Location&quot; 属性说明：这是存储浏览信息数据库和 IntelliSense 文件的第二个位置，如果不指定则放置到临时目录中；到临时目录一看，里面有一个 VC++ 的目录，都在那个目录里面呢。    <br />可以在 &quot;Fallback Location&quot; 属性中，设置一个固定的路径来存储这些文件，比如D:\VS2010Temp，这样也比较好管理这些庞大的臃肿的文件，可以定期清理掉它们，释放出硬盘空间！    <br />原文出处：<a href="http://www.cnblogs.com/rogee/archive/2010/10/30/1865062.html">http://www.cnblogs.com/rogee/archive/2010/10/30/1865062.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/vc-2010-%e9%a1%b9%e7%9b%ae%e8%bf%87%e5%a4%a7-%e9%97%ae%e9%a2%98%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>简单设置提高VS2010的运行速度</title>
		<link>http://www.buguw.com/%e7%ae%80%e5%8d%95%e8%ae%be%e7%bd%ae%e6%8f%90%e9%ab%98vs2010%e7%9a%84%e8%bf%90%e8%a1%8c%e9%80%9f%e5%ba%a6.html</link>
		<comments>http://www.buguw.com/%e7%ae%80%e5%8d%95%e8%ae%be%e7%bd%ae%e6%8f%90%e9%ab%98vs2010%e7%9a%84%e8%bf%90%e8%a1%8c%e9%80%9f%e5%ba%a6.html#comments</comments>
		<pubDate>Sun, 10 Apr 2011 06:30:51 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[编程学习经验]]></category>
		<category><![CDATA[vs2010]]></category>

		<guid isPermaLink="false">http://www.buguw.com/%e7%ae%80%e5%8d%95%e8%ae%be%e7%bd%ae%e6%8f%90%e9%ab%98vs2010%e7%9a%84%e8%bf%90%e8%a1%8c%e9%80%9f%e5%ba%a6.html</guid>
		<description><![CDATA[一、VS2010选项视觉体验设置 工具-&#62;选项-&#62;环境 视觉体验的勾选都去掉。不解释，你懂得。 二、禁用Intellisense 工具-&#62;选项-&#62;文本编辑器-&#62;C/C++-&#62;高级 禁用IntelliSense设为True 这个功能很好用。相较于Visual Assist X,Intellisence结果更加准确，但活动也更加频繁，项目一庞大时修改头起来就会使VS变得很卡。 三、下载Windows 自动化 API 3.0 更新包 微软安装说明： 安装 Windows 自动化 API 3.0 后，Visual Studio 2010 的运行速度更快。 如果未安装 Windows 自动化 API 3.0，则 Windows 笔和触摸服务会明显降低 Visual Studio IntelliSense 的性能 已经禁用IntelliSense的话这个就没什么用了。 下载页面：http://support.microsoft.com/kb/971513/zh-cn 四、关闭导航栏(不建议) 工具-&#62;选项-&#62;C#-&#62;常规 取消勾选导航栏 导航栏还是相当好用的，我是不建议去掉他。 五、取消修订 工具-&#62;选项-&#62;常规 减少开销,加速IDE的反应 六、取消跟踪活动项 工具-&#62;选项-&#62;项目和解决方案 取消 在解决方案资源管理器中跟踪活动项 七、取消重构 工具-&#62;选项-&#62;项目和解决方案 EnableRefactoringOnRename设为False 八、禁用IntelliTrace IntelliTrace是VS2010的新特征 默认启用并仅收集IntelliTrace事件。 目前还不太了解这个功能，但看其介绍是相当有利于开发的，不过同时，资源的消耗也是必然的。 [...]]]></description>
			<content:encoded><![CDATA[<p>一、VS2010选项视觉体验设置   <br /> 工具-&gt;选项-&gt;环境    <br /> 视觉体验的勾选都去掉。不解释，你懂得。    <br /> 二、禁用Intellisense    <br /> 工具-&gt;选项-&gt;文本编辑器-&gt;C/C++-&gt;高级    <br /> 禁用IntelliSense设为True    <br /> 这个功能很好用。相较于Visual Assist X,Intellisence结果更加准确，但活动也更加频繁，项目一庞大时修改头起来就会使VS变得很卡。    <br />三、下载Windows 自动化 API 3.0 更新包    <br /> 微软安装说明：    <br /> 安装 Windows 自动化 API 3.0 后，Visual Studio 2010 的运行速度更快。    <br /> 如果未安装 Windows 自动化 API 3.0，则 Windows 笔和触摸服务会明显降低 Visual Studio IntelliSense 的性能    <br /> 已经禁用IntelliSense的话这个就没什么用了。    <br /> 下载页面：http://support.microsoft.com/kb/971513/zh-cn    <br /> 四、关闭导航栏(不建议)    <br /> 工具-&gt;选项-&gt;C#-&gt;常规    <br /> 取消勾选导航栏    <br /> 导航栏还是相当好用的，我是不建议去掉他。    <br />五、取消修订    <br /> 工具-&gt;选项-&gt;常规    <br /> 减少开销,加速IDE的反应    <br /> 六、取消跟踪活动项    <br /> 工具-&gt;选项-&gt;项目和解决方案    <br /> 取消 在解决方案资源管理器中跟踪活动项    <br /> 七、取消重构    <br /> 工具-&gt;选项-&gt;项目和解决方案    <br /> EnableRefactoringOnRename设为False    <br />八、禁用IntelliTrace    <br /> IntelliTrace是VS2010的新特征    <br /> 默认启用并仅收集IntelliTrace事件。    <br /> 目前还不太了解这个功能，但看其介绍是相当有利于开发的，不过同时，资源的消耗也是必然的。    <br /> 禁用方法，工具-&gt;选项-&gt;IntelliTrace</p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/%e7%ae%80%e5%8d%95%e8%ae%be%e7%bd%ae%e6%8f%90%e9%ab%98vs2010%e7%9a%84%e8%bf%90%e8%a1%8c%e9%80%9f%e5%ba%a6.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>成员函数或友元函数做为线程函数【转载】</title>
		<link>http://www.buguw.com/%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0%e6%88%96%e5%8f%8b%e5%85%83%e5%87%bd%e6%95%b0%e5%81%9a%e4%b8%ba%e7%ba%bf%e7%a8%8b%e5%87%bd%e6%95%b0%e3%80%90%e8%bd%ac%e8%bd%bd%e3%80%91.html</link>
		<comments>http://www.buguw.com/%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0%e6%88%96%e5%8f%8b%e5%85%83%e5%87%bd%e6%95%b0%e5%81%9a%e4%b8%ba%e7%ba%bf%e7%a8%8b%e5%87%bd%e6%95%b0%e3%80%90%e8%bd%ac%e8%bd%bd%e3%80%91.html#comments</comments>
		<pubDate>Sat, 02 Apr 2011 04:33:52 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[WinSDK & MFC]]></category>
		<category><![CDATA[友元，函数，线程]]></category>

		<guid isPermaLink="false">http://www.buguw.com/%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0%e6%88%96%e5%8f%8b%e5%85%83%e5%87%bd%e6%95%b0%e5%81%9a%e4%b8%ba%e7%ba%bf%e7%a8%8b%e5%87%bd%e6%95%b0%e3%80%90%e8%bd%ac%e8%bd%bd%e3%80%91.html</guid>
		<description><![CDATA[WIN32线程控制主要实现线程的创建、终止、挂起和恢复等操作，这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数。 1.线程函数　　在启动一个线程之前，必须为线程编写一个全局的线程函数，这个线程函数接受一个32位的LPVOID作为参数，返回一个UINT，线程函数的结构为： UINT ThreadFunction(LPVOID pParam) { 　//线程处理代码 　return0; } 复制代码 　　在线程处理代码部分通常包括一个死循环，该循环中先等待某事情的发生，再处理相关的工作： while(1) { 　WaitForSingleObject(…,…);//或WaitForMultipleObjects(…) 　//Do something } 复制代码 　　一般来说，C++的类成员函数不能作为线程函数。这是因为在类中定义的成员函数，编译器会给其加上this指针。请看下列程序： ＃include "windows.h" ＃include &#60;process.h&#62; class ExampleTask { 　public: 　　void taskmain(LPVOID param); 　　void StartTask(); }; void ExampleTask::taskmain(LPVOID param) {} void ExampleTask::StartTask() { 　_beginthread(taskmain,0,NULL); } int main(int argc, char* argv[]) { 　ExampleTask realTimeTask; 　realTimeTask.StartTask(); 　return 0; } 复制代码 [...]]]></description>
			<content:encoded><![CDATA[<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">WIN32线程控制主要实现线程的创建、终止、挂起和恢复等操作，这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数。</p>
<p>1.线程函数<br />　　在启动一个线程之前，必须为线程编写一个全局的线程函数，这个线程函数接受一个32位的LPVOID作为参数，返回一个UINT，线程函数的结构为：</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code0">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">UINT ThreadFunction(LPVOID pParam)</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　//线程处理代码</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">　　在线程处理代码部分通常包括一个死循环，该循环中先等待某事情的发生，再处理相关的工作：</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code1">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">while(1)</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　WaitForSingleObject(…,…);//或WaitForMultipleObjects(…)</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　//Do something</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">　　一般来说，C++的类成员函数不能作为线程函数。这是因为在类中定义的成员函数，编译器会给其加上this指针。请看下列程序：</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code2">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include "windows.h"</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include &lt;process.h&gt;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">class ExampleTask </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　public: </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void taskmain(LPVOID param); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void StartTask(); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::taskmain(LPVOID param) </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::StartTask() </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　_beginthread(taskmain,0,NULL);</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">int main(int argc, char* argv[])</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　ExampleTask realTimeTask;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　realTimeTask.StartTask();</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return 0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">} </font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">　　程序编译时出现如下错误：<br />error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'<br />None of the functions with this name in scope match the target type </p>
<p>　　再看下列程序：</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code3">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include "windows.h"</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include &lt;process.h&gt;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">class ExampleTask </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　public: </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void taskmain(LPVOID param); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::taskmain(LPVOID param) </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">int main(int argc, char* argv[])</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　ExampleTask realTimeTask;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　_beginthread(ExampleTask::taskmain,0,NULL);</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return 0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">　　程序编译时会出错：<br />error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'<br />None of the functions with this name in scope match the target type </p>
<p>　　如果一定要以类成员函数作为线程函数，通常有如下解决方案：</p>
<p>　　<strong style="line-height: 1.5; margin: 0px; word-wrap: break-word">（1）将该成员函数声明为static类型，去掉this指针；</strong><br />　　我们将上述二个程序改变为：</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code4">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include"windows.h"</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include&lt;process.h&gt;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">class ExampleTask </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　public: </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void static taskmain(LPVOID param); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void StartTask(); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::taskmain(LPVOID param) </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::StartTask() </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　_beginthread(taskmain,0,NULL);</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">int main(int argc, char* argv[])</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　ExampleTask realTimeTask;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　realTimeTask.StartTask();</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return 0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">和</font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code5">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include "windows.h"</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include &lt;process.h&gt;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">class ExampleTask </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　public: </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void static taskmain(LPVOID param); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::taskmain(LPVOID param) </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">int main(int argc, char* argv[])</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　_beginthread(ExampleTask::taskmain,0,NULL);</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return 0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">　　均编译通过。</p>
<p>　　将成员函数声明为静态虽然可以解决作为线程函数的问题，但是它带来了新的问题，那就是static成员函数只能访问static成员。解决此问题的一种途径是可以在调用类静态成员函数（线程函数）时将this指针作为参数传入，并在改线程函数中用强制类型转换将this转换成指向该类的指针，通过该指针访问非静态成员。</p>
<p>　　</font></font><font face="Tahoma"><font style="font-size: 10.5pt"><font color="#444444"><strong style="line-height: 1.5; margin: 0px; word-wrap: break-word">（2）不定义类成员函数为线程函数，而将线程函数定义为类的友元函数。<br />这样，线程函数也可以有类成员函数同等的权限；</strong> <br />　　我们将程序修改为：</font></font></font>
<div style="background-image: url(http://www.cctry.com/static/image/7DRC_images/codebg.gif); border-bottom: #ccc 1px solid; border-left: #ccc 1px solid; padding-bottom: 5px; line-height: 1.5; background-color: #f7f7f7; margin-top: 10px; padding-left: 10px; background-repeat: repeat-y; word-wrap: break-word; background-position: 0px 0px; margin-bottom: 10px; overflow: hidden; border-top: #ccc 1px solid; border-right: #ccc 1px solid; padding-top: 10px" class="blockcode">
<div id="code6">
<ol style="margin-left: 10px">
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include “windows.h"</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">＃include &lt;process.h&gt;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">class ExampleTask </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　public: </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　friend void taskmain(LPVOID param); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　　void StartTask(); </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void taskmain(LPVOID param) </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　ExampleTask * pTaskMain = (ExampleTask *) param; </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　//通过pTaskMain指针引用 </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">} </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">void ExampleTask::StartTask() </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{ </font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　_beginthread(taskmain,0,this);</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">int main(int argc, char* argv[])</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">{</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　ExampleTask realTimeTask;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　realTimeTask.StartTask();</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">　return 0;</font></font><br /> 
<li style="line-height: 16.2pt; margin: 0px 0px 0px 24px; padding-left: 10px"><font face="Consolas"><font style="font-size: 9pt" color="#666666">}</font></font></li>
</ol>
</div>
<p><font face="Tahoma"><font style="font-size: 9pt" color="#336699">复制代码</font></font></div>
<p><strong style="line-height: 1.5; margin: 0px; word-wrap: break-word"></p>
<p><font face="Tahoma"><font style="font-size: 10.5pt" color="#444444">（3）可以对非静态成员函数实现回调，并访问非静态成员，此法涉及到一些高级技巧，在此不再详述。</font></font></strong>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/%e6%88%90%e5%91%98%e5%87%bd%e6%95%b0%e6%88%96%e5%8f%8b%e5%85%83%e5%87%bd%e6%95%b0%e5%81%9a%e4%b8%ba%e7%ba%bf%e7%a8%8b%e5%87%bd%e6%95%b0%e3%80%90%e8%bd%ac%e8%bd%bd%e3%80%91.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转载]进程的虚拟地址空间</title>
		<link>http://www.buguw.com/%e8%bd%ac%e8%bd%bd%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%99%9a%e6%8b%9f%e5%9c%b0%e5%9d%80%e7%a9%ba%e9%97%b4.html</link>
		<comments>http://www.buguw.com/%e8%bd%ac%e8%bd%bd%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%99%9a%e6%8b%9f%e5%9c%b0%e5%9d%80%e7%a9%ba%e9%97%b4.html#comments</comments>
		<pubDate>Thu, 31 Mar 2011 11:55:13 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[编程学习经验]]></category>
		<category><![CDATA[进程]]></category>

		<guid isPermaLink="false">http://www.buguw.com/%e8%bd%ac%e8%bd%bd%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%99%9a%e6%8b%9f%e5%9c%b0%e5%9d%80%e7%a9%ba%e9%97%b4.html</guid>
		<description><![CDATA[昨晚看到了深夜，终于对进程的虚拟地址空间有了个大致的了解，很激动，也很欣慰。回头想来，一个程序员，真的应该知道这些知识，否则还真不太称职。 首先告诉大家，我后面提到的这些知识在《windows核心编程》中都有，强烈建议大家把这本书翻翻，我相信会对你的编程境界拔高好几个层次的。可是我最近没那么多时间，因此就只能了解个大概，然后等今后闲暇时再看这本书吧。 昨天我媳妇还反复和我说：学东西必须要有选择，不能对IT行业的所有知识乱学习，而且不要学那种实际意义不大的知识或是容易被淘汰的知识。其实她说的蛮对的，但是我要说，有关《windows核心编程》里的知识永远都不会过时，因为它侵入到底层和内部了，就像C++，你觉得会过时吗？就像windows永远不会被淘汰一样，呵呵。 下面我就来粗略的说说我了解的一些基本知识： 32位机器，每个程序有4G的虚拟地址空间。大致分为4块，从低地址到高地址依次是：NULL区，用户区，隔离区，核心区。用户私有的数据都在用户区（当然这个区里又可以细分，其中也包括一部分可以共享的内容），系统内核等东西都在核心区。总体来说，A进程的虚拟地址空间中的内容和B进程相比，只有各自的用户区不一致。通常用户区中，进程又会将exe文件（由头数据和段数据组成）中定义的代码段、堆栈段、数据段等各个段映射到用户区的特定不同部位。对于这部分区域，用户需要用VirtualAlloc先为自己预留后再提交，最后在自己的页面被cpu访问时再从exe映像中将数据加载到主存，然后将虚拟地址映射为主存的物理地址。基本上这样就可以了，至于系统如何进行页面的管理以及地址映射如何实现等细节请大家再参考别的文献。 我本以为很复杂呢，结果写出来，就这么一小段，呵呵，看来是高估了自己理解的东西了，呵呵。 下面贴出我看的一些资料： 虚拟存储器是一个抽象概念，它为每一个进程提供了一个假象，好像每个进程都在独占的使用主存。每个进程看到的存储器都是一致的，称之为虚拟地址空间。 每个进程看到得虚拟地址空间有大量准确定义的区（area）构成，每个区都有专门的功能。从最低的地址看起： 程序代码和数据：代码是从同一固定地址开始，紧接着的是和C全局变量相对应的数据区。 （应该就是所谓的静态存储空间） 堆：代码和数据区后紧随着的是运行时堆。作为调用malloc和free这样的C标准库函数，堆可以在运行时动态的扩展和收缩。（应该就是所谓的动态存储区） 共享库：在地址空间的中间附近是一块用来存放像C标准库和数学库这样共享库的代码和数据的区域。（C标准库函数的指令，连接阶段把他们加入到编译后的程序） 栈：位于用户虚拟地址空间顶部的是用户栈，编译器用它来实现函数调用。和堆一样每次我们从函数返回时，栈就会收缩。 内核虚拟存储器：内核是操作系统总是驻留在存储器中的部分。地址空间顶部的四分之一部分是为内核预留的。（系统函数？这里说的UNIX系统，不知道windows下是不是这样的？） 今天大多数计算机的字长都是32字节，这就限制了虚拟地址空间为4千兆字节（4GB） 引言 Windows的内存结构是深入理解Windows操作系统如何运作的最关键之所在，通过对内存结构的认识可清楚地了解诸如进程间数据的共享、对内存进行有效的管理等问题，从而能够在程序设计时使程序以更加有效的方式运行。Windows操作系统对内存的管理可采取多种不同的方式，其中虚拟内存的管理方式可用来管理大型的对象和结构数组。 在Windows系统中，任何一个进程都被赋予其自己的虚拟地址空间，该虚拟地址空间覆盖了一个相当大的范围，对于32位进程，其地址空间为232=4,294,967,296 Byte，这使得一个指针可以使用从0x00000000到0xFFFFFFFF的4GB范围之内的任何一个值。虽然每一个32位进程可使用4GB的地址空间，但并不意味着每一个进程实际拥有4GB的物理地址空间，该地址空间仅仅是一个虚拟地址空间，此虚拟地址空间只是内存地址的一个范围。进程实际可以得到的物理内存要远小于其虚拟地址空间。进程的虚拟地址空间是为每个进程所私有的，在进程内运行的线程对内存空间的访问都被限制在调用进程之内，而不能访问属于其他进程的内存空间。这样，在不同的进程中可以使用相同地址的指针来指向属于各自调用进程的内容而不会由此引起混乱。下面分别对虚拟内存的各具体技术进行介绍。 地址空间中区域的保留与释放 在进程创建之初并被赋予地址空间时，其虚拟地址空间尚未分配，处于空闲状态。这时地址空间内的内存是不能使用的，必须首先通过VirtualAlloc（）函数来分配其内的各个区域，对其进行保留。 LPVOID VirtualAlloc( LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect ); 其参数lpAddress包含一个内存地址，用于定义待分配区域的首地址。通常可将此参数设置为NULL，由系统通过搜索地址空间来决定满足条件的未保留地址空间。这时系统可从地址空间的任意位置处开始保留一个区域，而且还可以通过向参数flAllocationType设置MEM_TOP_DOWN标志来指明在尽可能高的地址上分配内存。如果不希望由系统自动完成对内存区域的分配而为lpAddress设定了内存地址（必须确保其始终位于进程的用户模式分区中，否则将会导致分配的失败），那么系统将在进行分配之前首先检查在该内存地址上是否存在足够大的未保留空间，如果存在一个足够大的空闲区域，那么系统将会保留此区域并返回此保留区域的虚拟地址，否则将导致分配的失败而返回NULL。这里需要特别指出的是，在指定lpAddress的内存地址时，必须确保是从一个分配粒度的边界处开始。 一般来说，在不同的CPU平台下分配粒度各不相同，但目前所有Windows环境下的CPU如x86、32位Alpha、64位Alpha以及IA-64等均是采用64KB的分配粒度。如果保留区域的起始地址没有遵循从64KB分配粒度的边界开始之一原则，系统将自动调整该地址到最接近的64K的倍数。例如，如果指定的lpAddress为0x00781022，那么此保留区域实际是从0x00780000开始分配的。参数dwSize指定了保留区域的大小。但是系统实际保留的区域大小必须是CPU页面大小的整数倍，如果指定的dwSize并非CPU页面的整数倍，系统将自动对其进行调整，使其达到与之最接近的页面大小整数倍。与分配粒度一样，对于不同的CPU平台其页面大小也是不一样的。在x86平台下，页面大小为4KB，在32位Alpah平台下，页面大小为8KB。在使用时可以通过GetSystemInfo（）来决定当前主机的页面大小。参数flAllocationType和flProtect分别定义了分配类型和访问保护属性。由于VirtualAlloc（）可用来保留一个区域也可以用来占用物理存储器，因此通过flAllocationType来指定当前是要保留一个区域还是要占用物理存储器。其可能使用的内存分配类型有： 分配类型 类型说明 MEM_COMMIT 为特定的页面区域分配内存中或磁盘的页面文件中的物理存储 MEM_PHYSICAL 分配物理内存（仅用于地址窗口扩展内存） MEM_RESERVE 保留进程的虚拟地址空间，而不分配任何物理存储。保留页面可通过继续调用VirtualAlloc（）而被占用 MEM_RESET 指明在内存中由参数lpAddress和dwSize指定的数据无效 MEM_TOP_DOWN 在尽可能高的地址上分配内存（Windows 98忽略此标志） MEM_WRITE_WATCH 必须与MEM_RESERVE一起指定，使系统跟踪那些被写入分配区域的页面（仅针对Windows 98） 分配成功完成后，即在进程的虚拟地址空间中保留了一个区域，可以对此区域中的内存进行保护权限许可范围内的访问。当不再需要访问此地址空间区域时，应释放此区域。由VirtualFree（）负责完成。其函数原型为： BOOL VirtualFree( LPVOID [...]]]></description>
			<content:encoded><![CDATA[<div style="line-height: 16pt" class="postbody">
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">昨晚看到了深夜，终于对进程的虚拟地址空间有了个大致的了解，很激动，也很欣慰。回头想来，一个程序员，真的应该知道这些知识，否则还真不太称职。         <br />首先告诉大家，我后面提到的这些知识在《windows核心编程》中都有，强烈建议大家把这本书翻翻，我相信会对你的编程境界拔高好几个层次的。可是我最近没那么多时间，因此就只能了解个大概，然后等今后闲暇时再看这本书吧。          <br />昨天我媳妇还反复和我说：学东西必须要有选择，不能对IT行业的所有知识乱学习，而且不要学那种实际意义不大的知识或是容易被淘汰的知识。其实她说的蛮对的，但是我要说，有关《windows核心编程》里的知识永远都不会过时，因为它侵入到底层和内部了，就像C++，你觉得会过时吗？就像windows永远不会被淘汰一样，呵呵。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">下面我就来粗略的说说我了解的一些基本知识：         <br />32位机器，每个程序有4G的虚拟地址空间。大致分为4块，从低地址到高地址依次是：NULL区，用户区，隔离区，核心区。用户私有的数据都在用户区（当然这个区里又可以细分，其中也包括一部分可以共享的内容），系统内核等东西都在核心区。总体来说，A进程的虚拟地址空间中的内容和B进程相比，只有各自的用户区不一致。通常用户区中，进程又会将exe文件（由头数据和段数据组成）中定义的代码段、堆栈段、数据段等各个段映射到用户区的特定不同部位。对于这部分区域，用户需要用VirtualAlloc先为自己预留后再提交，最后在自己的页面被cpu访问时再从exe映像中将数据加载到主存，然后将虚拟地址映射为主存的物理地址。基本上这样就可以了，至于系统如何进行页面的管理以及地址映射如何实现等细节请大家再参考别的文献。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">我本以为很复杂呢，结果写出来，就这么一小段，呵呵，看来是高估了自己理解的东西了，呵呵。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">下面贴出我看的一些资料：</font></font>      </p>
<div style="layout-grid:  15.6pt none" class="Section1">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; color: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font style="background-color: #ff0000" face="宋体"><font style="font-size: 10.5pt">虚拟存储器是一个抽象概念，它为每一个进程提供了一个假象，好像每个进程都在独占的使用主存。每个进程看到的存储器都是一致的，称之为虚拟地址空间。</font></font></span><span style="color: " lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">每个进程看到得虚拟地址空间有大量准确定义的区（</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">area</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">）构成，每个区都有专门的功能。<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">从最低的地址看起</font></span>：</font></font></span></p>
<ul style="list-style-type: disc; margin-left: 30pt" type="disc">
<li style="text-align: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l0 level1 lfo1" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">程序代码和数据：代码是从同一固定地址开始，紧接着的是和</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">C</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">全局变量相对应的数据区。</font></span><font face="Arial"> </font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">（应该就是所谓的静态存储空间）</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></li>
<li style="text-align: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l0 level1 lfo1" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">堆：代码和数据区后紧随着的是运行时堆。作为调用</font></font></span><font style="font-size: 10.5pt"><span class="SpellE"><span lang="EN-US"><font face="Arial">malloc</font></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span lang="EN-US"><font face="Arial">free</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">这样的</font></span><span lang="EN-US"><font face="Arial">C</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">标准库函数，<span class="GramE">堆可以</span>在运行时动态的扩展和收缩。（应该就是所谓的动态存储区）</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></li>
<li style="text-align: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l0 level1 lfo1" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">共享库：在地址空间的中间附近是一块用来存放像</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">C</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">标准库和数学库这样共享库的代码和数据的区域。（</font></span><span lang="EN-US"><font face="Arial">C</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">标准库函数的指令，连接阶段把他们加入到编译后的程序）</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></li>
<li style="text-align: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l0 level1 lfo1" class="MsoNormal"><font face="宋体"><span class="GramE"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font style="font-size: 10.5pt">栈</font></span></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;">：位于用户虚拟地址空间顶部的是用户<span class="GramE">栈</span>，编译器用它来实现函数调用。和<span class="GramE">堆一样</span>每次我们从函数返回时，<span class="GramE">栈</span>就会收缩。</span></font></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></li>
<li style="text-align: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 36.0pt; mso-list: l0 level1 lfo1" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">内核虚拟存储器：内核是操作系统总是驻留在存储器中的部分。地址空间顶部的四<span class="GramE">分之一</span>部分是为内核预留的。（系统函数？这里说的</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">UNIX</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">系统，不知道</font></span><span lang="EN-US"><font face="Arial">windows</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">下是不是这样的？）</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></li>
</ul>
<div style="border-bottom: windowtext 2.25pt double; border-left: medium none; padding-bottom: 1pt; padding-left: 0cm; padding-right: 0cm; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-element: para-border-div">
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span><font face="Arial"><font style="font-size: 10.5pt">今天大多数计算机的字长都是<span lang="EN-US">32</span>字节，这就限制了虚拟地址空间为<span lang="EN-US">4</span>千兆字节（<span lang="EN-US">4GB</span>）</font></font></p>
</p></div>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">引言</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt"> <font style="background-color: #ff0000"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US">Windows</span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red">的内存结构是深入理解<span lang="EN-US">Windows</span>操作系统如何运作的<span class="GramE">最</span>关键之所在，通过对内存结构的认识可清楚地了解诸如进程<span class="GramE">间数据</span>的共享、对内存进行有效的管理等问题，从而能够在程序设计时使程序以更加有效的方式运行。</span></font><span lang="EN-US">Windows</span>操作系统对内存的管理可采取多种不同的方式，其中虚拟内存的管理方式可用来管理大型的对象和结构数组。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt"> 在<span lang="EN-US">Windows</span>系统中，任何一个进程都被赋予其自己的虚拟地址空间，该虚拟地址空间覆盖了一个相当大的范围，对于<span lang="EN-US">32</span>位进程，其地址空间为<span lang="EN-US">232=4,294,967,296 Byte</span>，这使得一个指针可以使用从<span lang="EN-US">0x00000000</span>到<span lang="EN-US">0xFFFFFFFF</span>的<span lang="EN-US">4GB</span>范围之内的任何一个值。<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">虽然每一个<span lang="EN-US">32</span>位进程可使用<span lang="EN-US">4GB</span>的地址空间，但并不意味着每一个进程实际拥有<span lang="EN-US">4GB</span>的物理地址空间，该地址空间仅仅是一个虚拟地址空间，此虚拟地址空间只是内存地址的一个范围。进程实际可以得到的物理内存要远小于其虚拟地址空间。进程的虚拟地址空间是为每个进程所私有的，在进程内运行的线程对内存空间的访问都被限制在调用进程之内，而不能访问属于其他进程的内存空间。这样，在不同的进程中可以使用相同地址的指针来指向属于各自调用进程的内容而不会由此引起混乱。</font></span>下面分别对虚拟内存的各具体技术进行介绍。</font></font><font style="font-size: 10.5pt"><span lang="EN-US">           <br /></span></font><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">地址空间中区域的保留与释放</font></font></span></strong></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">在进程创建<span class="GramE">之初并被</span>赋予地址空间时，其虚拟地址空间尚未分配，处于空闲状态。这时地址空间内的内存是不能使用的，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">必须首先通过<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）函数来分配其内的各个区域，对其进行保留</font></span>。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">LPVOID <span class="SpellE">VirtualAlloc</span>(              <br /></font></span><font style="font-size: 10.5pt"> </font></font><font style="font-size: 10.5pt"><font face="Arial"><span lang="EN-US">LPVOID <span class="SpellE">lpAddress</span>,               <br /></span> </font><font face="Arial"><span lang="EN-US">DWORD <span class="SpellE">dwSize</span>,               <br /></span> </font><font face="Arial"><span lang="EN-US">DWORD <span class="SpellE">flAllocationType</span>,              <br /></span> </font></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">DWORD <span class="SpellE">flProtect</span>              <br />);</font></font></span></p>
<p style="margin-bottom: 12pt"><font face="Arial"><font style="font-size: 10.5pt">其参数<span class="SpellE"><span lang="EN-US">lpAddress</span></span>包含一个内存地址，用于定义待分配区域的首地址。通常可将此参数设置为<span lang="EN-US">NULL</span>，由系统通过搜索地址空间来决定满足条件的未保留地址空间。这时系统可从地址空间的任意位置处开始保留一个区域，而且还可以通过向参数<span class="SpellE"><span lang="EN-US">flAllocationType</span></span>设置<span lang="EN-US">MEM_TOP_DOWN</span>标志来指明在尽可能高的地址上分配内存。如果不希望由系统自动完成对内存区域的分配而为<span class="SpellE"><span lang="EN-US">lpAddress</span></span>设定了内存地址（<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">必须确保其始终位于进程的用户模式分区中，否则将会导致分配的失败</font></span>），那么系统将在进行分配之前首先检查在该内存地址上是否存在足够大的未保留空间，如果存在一个足够大的空闲区域，那么系统将会保留此区域并返回此保留区域的虚拟地址，否则将导致分配的失败而返回<span lang="EN-US">NULL</span>。这里需要特别指出的是，在指定<span class="SpellE"><span lang="EN-US">lpAddress</span></span>的内存地址时，必须确保是从一个分配粒度的边界处开始。</font></font><font style="font-size: 10.5pt"><span lang="EN-US">           <br /></span></font><font face="Arial"><font style="font-size: 10.5pt">一般来说，在不同的<span lang="EN-US">CPU</span>平台下分配粒度各不相同，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">但目前所有<span lang="EN-US">Windows</span>环境下的<span lang="EN-US">CPU</span>如<span lang="EN-US">x86</span>、<span lang="EN-US">32</span>位<span lang="EN-US">Alpha</span>、<span lang="EN-US">64</span>位<span lang="EN-US">Alpha</span>以及<span lang="EN-US">IA-64</span>等均是采用<span lang="EN-US">64KB</span>的分配粒度。</font></span>如果保留区域的起始地址没有遵循从<span lang="EN-US">64KB</span>分配粒度的边界开始之一原则，系统将自动调整该地址到最接近的<span lang="EN-US">64K</span>的倍数。例如，如果指定的<span class="SpellE"><span lang="EN-US">lpAddress</span></span>为<span lang="EN-US">0x00781022</span>，那么此保留区域实际是从<span lang="EN-US">0x00780000</span>开始分配的。参数<span class="SpellE"><span lang="EN-US">dwSize</span></span>指定了保留区域的大小。但是系统实际保留的区域大小必须是<span lang="EN-US">CPU</span>页面大小的整数<span class="GramE">倍</span>，如果指定的<span class="SpellE"><span lang="EN-US">dwSize</span></span>并非<span lang="EN-US">CPU</span>页面的整数<span class="GramE">倍</span>，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">系统将自动对其进行调整，使其达到与之最接近的页面大小整数<span class="GramE">倍</span>。</font></span>与分配粒度一样，对于不同的<span lang="EN-US">CPU</span>平台其页面大小也是不一样的。在<span lang="EN-US">x86</span>平台下，页面大小为<span lang="EN-US">4KB</span>，在<span lang="EN-US">32</span>位<span class="SpellE"><span lang="EN-US">Alpah</span></span>平台下，页面大小为<span lang="EN-US">8KB</span>。在使用时可以通过<span class="SpellE"><span lang="EN-US">GetSystemInfo</span></span>（）来决定当前主机的页面大小。参数<span class="SpellE"><span lang="EN-US">flAllocationType</span></span>和<span class="SpellE"><span lang="EN-US">flProtect</span></span>分别定义了分配类型和访问保护属性。由于<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）可用来保留一个区域也可以用来占用物理存储器，因此通过<span class="SpellE"><span lang="EN-US">flAllocationType</span></span>来指定当前是要保留一个区域还是要占用物理存储器。其可能使用的内存分配类型有：</font></font></p>
<table style="line-height: normal; mso-cellspacing: 0cm" class="MsoNormalTable" border="1" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">分配类型</font></font></span><font face="Arial"><font style="font-size: 10.5pt"> </font><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></font></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">类型说明</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_COMMIT</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="background-color: #ff0000; font-size: 10.5pt">为特定的页面区域分配内存中或磁盘的页面文件中的物理存储</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_PHYSICAL </font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">分配物理内存（仅用于地址窗口扩展内存）</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 3">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_RESERVE</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">保留进程的虚拟地址空间，而不分配任何物理存储。保留页面可通过继续调用</font></font></span><font style="font-size: 10.5pt"><span class="SpellE"><span lang="EN-US"><font face="Arial">VirtualAlloc</font></span></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">（）而被占用</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_RESET </font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">指明在内存中由参数</font></font></span><font style="font-size: 10.5pt"><span class="SpellE"><span lang="EN-US"><font face="Arial">lpAddress</font></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span class="SpellE"><span lang="EN-US"><font face="Arial">dwSize</font></span></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">指定的数据无效</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 5">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_TOP_DOWN</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">在尽可能高的地址上分配内存（</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Windows 98</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">忽略此标志）</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 6; mso-yfti-lastrow: yes">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEM_WRITE_WATCH</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">必须与</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">MEM_RESERVE</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">一起指定，使系统跟踪那些被写入分配区域的页面（仅针对</font></span><span lang="EN-US"><font face="Arial">Windows 98</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">）</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 12pt"><span lang="EN-US">         <br /></span><font face="Arial"><font style="font-size: 10.5pt"> 分配成功完成后，即在进程的虚拟地址空间中保留了一个区域，可以对此区域中的内存进行保护权限许可范围内的访问。当不再需要<span class="GramE">访问此</span>地址空间区域时，应释放此区域。由<span class="SpellE"><span lang="EN-US">VirtualFree</span></span>（）负责完成。其函数原型为：</font></font></p>
<table style="line-height: normal; background: white; mso-cellspacing: 1.5pt" class="MsoNormalTable" border="0" cellpadding="0" width="100%">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<td style="padding-bottom: 0.75pt; padding-left: 0.75pt; padding-right: 0.75pt; padding-top: 0.75pt">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">BOOL <span class="SpellE">VirtualFree</span>(</font></font><font style="font-size: 10.5pt">                   <br /></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"> </font></span><span lang="EN-US"><font face="Arial">LPVOID <span class="SpellE">lpAddress</span>,</font>                    <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"> </font></span><span lang="EN-US"><font face="Arial">DWORD <span class="SpellE">dwSize</span>,</font>                    <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"> </font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">DWORD <span class="SpellE">dwFreeType</span>                      <br />);</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">其中，参数<span class="SpellE"><span lang="EN-US">lpAddress</span></span>为指向待释放页面区域的指针。如果参数<span class="SpellE"><span lang="EN-US">dwFreeType</span></span>指定了<span lang="EN-US">MEM_RELEASE</span>，则<span class="SpellE"><span lang="EN-US">lpAddress</span></span>必须为页面区域被保留时由<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）所返回的基地址。参数<span class="SpellE"><span lang="EN-US">dwSize</span></span>指定了要释放的地址空间区域的大小，如果参数<span class="SpellE"><span lang="EN-US">dwFreeType</span></span>指定了<span lang="EN-US">MEM_RELEASE</span>标志，则将<span class="SpellE"><span lang="EN-US">dwSize</span></span>设置为<span lang="EN-US">0</span>，由系统计算在特定内存地址上的待释放区域的大小。参数<span class="SpellE"><span lang="EN-US">dwFreeType</span></span>为所执行的释放操作的类型，其可能的取值为<span lang="EN-US">MEM_RELEASE</span>和<span lang="EN-US">MEM_DECOMMIT</span>，其中<span lang="EN-US">MEM_RELEASE</span>标志指明要释放指定的保留页面区域，<span lang="EN-US">MEM_DECOMMIT</span>标志则对指定的占用页面区域进行占用的解除。如果<span class="SpellE"><span lang="EN-US">VirtualFree</span></span>（）成功执行完成，将回收全部范围的已分配页面，此后如再对这些已释放页面区域内存的访问将引发内存访问异常。释放后的页面区域可供系统继续分配使用。</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt"> 下面这段代码演示了由系统在进程的用户模式分区内保留一个<span lang="EN-US">64KB</span>大小的区域，并将其释放的过程：</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">在地址空间中保留一个区域</font></font></p>
<p style="margin-bottom: 14px"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">LPBYTE <span class="SpellE">bBuffer</span> = (LPBYTE<span class="GramE">)<span class="SpellE">VirtualAlloc</span></span>(NULL, 65536, MEM_RESERVE, PAGE_READWRITE);</font></font></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">……</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">释放已保留的区域</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualFree</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">bBuffer</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">, 0, MEM_RELEASE);</font></span></font></p>
<h3 style="border-bottom: #aaa 1px solid; line-height: 17pt; padding-left: 10px; background: #f9fcfe; margin-left: 10px; word-break: break-all; margin-right: 10px"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">flProtect</font></span></span><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font style="font-size: 10.5pt">页面保护属性</font></span></font><span style="font-family: " lang="EN-US"></span></h3>
<p style="line-height: 16.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">我们可以给每个已分配的物理存储页指定不同的页面保护属性。表</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">13-3</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">列出了所有的页面保护属性。</font></font></span><span style="font-family: " lang="EN-US"></span></p>
<h5 style="line-height: 17pt; margin: 7.8pt 0cm; background: #f9fcfe; word-break: break-all"><font face="Arial"><font style="font-size: 10.5pt">表<span lang="EN-US">13-3 </span></font></font><span style="font-family: "><font face="黑体"><font style="font-size: 10.5pt">内存页面保护属性</font><span lang="EN-US"></span></font></span></h5>
<div align="center">
<table style="text-align: left; line-height: normal; border-collapse: collapse; mso-padding-alt: 0cm 0cm 0cm 0cm" class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" width="548">
<thead>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: windowtext 1.5pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="a4"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">保护属性</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: windowtext 1.5pt solid; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="a4"><font face="Arial"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font style="font-size: 6pt">描</font></span><font style="font-size: 6pt"><span style="font-family: " lang="EN-US"> </span></font></font><span style="font-family: ; mso-hansi-font-family: ˎ̥"><font face="黑体"><font style="font-size: 6pt">述</font><span lang="EN-US"></span></font></span></p>
</td>
</tr>
</thead>
<tbody>
<tr style="mso-yfti-irow: 1">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_NOACCESS</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">试图读取页面、写入页面或执行页面中的代码将引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_READONLY</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">试图写入页面或执行页面中的代码将引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 3">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_READWRITE</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">试图执行页面中的代码将引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_EXECUTE</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">试图读取页面或写入页面将引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 5">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_EXECUTE_READ</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">试图写入页面将引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 6">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_EXECUTE_READWRITE</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font face="Arial"><font style="font-size: 6pt">对页面执行任何操作都不会引发访问违规</font></font></span><span style="font-family: " lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 7">
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_WRITECOPY</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><font face="Arial"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font style="font-size: 6pt">试图执行页面中的代码将引发访问违规。试图写入页面将使系统<span class="GramE">为进程</span>单独创建一份该页面的私有副本</font></span><font style="font-size: 6pt"><span style="font-family: " lang="EN-US">(</span><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥">以页交换文件为后备存储器</span></font><span style="font-family: " lang="EN-US"><font style="font-size: 6pt">)</font></span></font></p>
</td>
</tr>
<tr style="mso-yfti-irow: 8; mso-yfti-lastrow: yes">
<td style="border-bottom: windowtext 1.5pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="186">
<p style="margin-bottom: 14px" class="af7"><span style="font-family: " lang="EN-US"><font face="Arial"><font style="font-size: 6pt">PAGE_EXECUTE_WRITECOPY</font></font></span></p>
</td>
<td style="border-bottom: windowtext 1.5pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; padding-right: 5.4pt; border-top: medium none; border-right: medium none; padding-top: 0cm" valign="top" width="362">
<p style="margin-bottom: 14px" class="af7"><font face="Arial"><span style="mso-ascii-font-family: ˎ̥; mso-hansi-font-family: ˎ̥"><font style="font-size: 6pt">对页面执行任何操作都不会引发访问违规。试图写入页面将使系统<span class="GramE">为进程</span>单独创建一份该页面的私有副本</font></span><font style="font-size: 6pt"><span style="letter-spacing: -0.1pt; font-family: " lang="EN-US">(</span></font><span style="letter-spacing: -0.1pt"><font style="font-size: 6pt">以页交换文件为后备存储器</font><span lang="EN-US"><font style="font-size: 6pt">)</font></span></span></font></p>
</td>
</tr>
</tbody>
</table></div>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">一些恶意软件将代码写入到用于数据的内存区域</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">(</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">比如线程<span class="GramE">栈</span>上</font></span><span lang="EN-US"><font face="Arial">)</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，通过这种方式让应用程序执行恶意代码。</font></span><span lang="EN-US"><font face="Arial">Windows</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的</font></span><span style="font-family: "><font face="黑体">数据执行保护</font></span><span lang="EN-US"><font face="Arial">(Data Execution Protection</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，后面简称为</font></span><span lang="EN-US"><font face="Arial">DEP)</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">特性提供了对此类恶意攻击的防护。如果启用了</font></span><span lang="EN-US"><font face="Arial">DEP</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，那么只有对那些真正需要执行代码的内存区域，操作系统才会使用</font></span><span class="inparagraphemphasischar"><span lang="EN-US"><font face="Arial">PAGE_EXECUTE_*</font></span></span><span class="inparagraphemphasischar"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">保护属性。其他保护属性</font></span><span lang="EN-US"><font face="Arial">(</font></span></span><span class="inparagraphemphasischar"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">最常见的就是</font></span><span lang="EN-US"><font face="Arial">PAGE_READWRITE<span style="letter-spacing: 0.3pt">)</span></font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">用于只应该存放数据的内存区域</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">(</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">比如线程<span class="GramE">栈</span>和应用程序的堆</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">)</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">。</font></font></span></span><span class="inparagraphemphasischar"><span style="line-height: 19pt; letter-spacing: 0.3pt; font-family: ; mso-hansi-font-family: &#39;Times New Roman&#39;" lang="EN-US"></span></span></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">如果</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">CPU</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">试图执行某个页面中的代码，而该页又没有</font></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_EXECUTE_*</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">保护属性，那么</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">CPU</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">会抛出访问违规异常。</font></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"></span></span></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">系统还对</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">Windows</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">支持的结构化异常处理机制</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">(structured exception handling mechanism)</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">做了更进一步的保护，结构化异常处理机制会在第</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">23</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">～</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">25</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">章详细介绍。如果应用程序在链接时使用了</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">/<span class="inparagraphemphasischar">SAFESEH</span></font></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">开关，那么异常处理器会被注册到映像文件中一个特殊的表中。这样，当将要执行一个异常处理器时，操作系统会先检查该处理器有没有在表中注册过，然后决定是否允许它执行。</font></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"></span></span></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">有关</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">DEP</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的更多信息，<span class="GramE">请访问</span></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">http://<span class="SpellE">go.microsoft.com/fwlink/?LinkId</span>=28022</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，可以在此找到</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">Microsoft</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">白皮书“</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">03_CIF_Memory_Protection.DOC</font></span></font><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">”。</font></font></span></p>
<p style="line-height: 17pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="41"><a name="_Toc189409068"><u><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"></span></u></a><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"></span></p>
<h3 style="border-bottom: #aaa 1px solid; line-height: 17pt; padding-left: 10px; background: #f9fcfe; margin-left: 10px; word-break: break-all; margin-right: 10px"><font face="Arial"><span style="letter-spacing: 0.3pt" lang="EN-US"><font style="font-size: 10.5pt">13.6.1</font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"> </span></font><span style="letter-spacing: 0.3pt"><font style="font-size: 10.5pt">写时复制</font><span lang="EN-US"></span></span></font></h3>
<p style="line-height: 15.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">在表</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">13.3</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中列出的保护属性中，除最后两个属性</font></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_WRITECOPY</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_EXECUTE_WRITECOPY</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">之外，其余的都不言自明。这两个保护属性存在的目的是为了节省内存和页交换文件的使用。</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">Windows</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">支持一种机制，允许两个或两个以上的进程共享同一块存储器。因此，如果有</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">10</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">个记事本程序正在运行，所有的进程会共享应用程序的代码页和数据页。让所有的应用程序实例共享相同的<span class="GramE">存储页极大地</span>提升了系统的性能，但另一方面，这也要求所有的应用程序实例只能读取其中的数据或是执行其中的代码。如果某个应用程序实例修改并写入一个存储页，那么这等于是修改了其他实例正在使用的存储页，最终将导致混乱。</font></font></span><span lang="EN-US"></span></span></p>
<p style="line-height: 15.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">为了避免此类混乱的发生，操作系统会给共享的存储页指定写时复制属性。当系统把一个</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">.exe</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">或</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">.<span class="SpellE">dll</span></font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">映射到一个地址空间的时候，系统会计算有多少页面是可写的。</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">(</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">通常，包含代码的页面被标记为</font></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_EXECUTE_READ</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，而包含数据的页面被标记为</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_READWRITE</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">。</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">)</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">然后系统会从页交换文件中分配存储空间来容纳这些可写页面。除非应用程序真的写入可写页面，否则不会用到页交换文件中的存储器。</font></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"></span></span></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">当线程试图写入一个共享页面时，系统会介入并执行下面的操作。</font></font></span></p>
<p style="line-height: 17pt; text-indent: -21pt; margin-bottom: 14px; background: #f9fcfe; margin-left: 21pt; word-break: break-all" class="af3"><font face="Arial"><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"><font style="font-size: 7.5pt">(1) </font></span><span style="line-height: 12pt; letter-spacing: 0.3pt"><font style="font-size: 7.5pt">系统在内存中找到一个闲置页面。注意，该闲置页面的后备页面来自页交换文件，它是系统最初将模块映射<span class="GramE">到进程</span>的地址空间时分配的。由于系统在第一次进行映射的时候分配了所有可能需要的页交换文件空间，这一步不可能失败。</font><span lang="EN-US"></span></span></font></p>
<p style="line-height: 17pt; text-indent: -21pt; margin-bottom: 14px; background: #f9fcfe; margin-left: 21pt; word-break: break-all" class="af3"><font face="Arial"><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"><font style="font-size: 7.5pt">(2) </font></span><span style="line-height: 12pt; letter-spacing: 0.3pt"><font style="font-size: 7.5pt">系统把线程想要修改的页面内容复制到在第<span lang="EN-US">1</span>步中找到的闲置页面。系统会给该闲置页面指定</font><span class="inparagraphemphasischar"><font style="font-size: 7.5pt"><span lang="EN-US">PAGE_READWRITE</span>或<span lang="EN-US">PAGE_EXECUTE_READWRITE</span>保护属性，系统不会对原始页面的保护属性和数据做任何修改。</font></span></span></font><span class="inparagraphemphasischar"><span lang="EN-US"></span></span></p>
<p style="line-height: 17pt; text-indent: -21pt; margin-bottom: 14px; background: #f9fcfe; margin-left: 21pt; word-break: break-all" class="af3"><font face="Arial"><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"><font style="font-size: 7.5pt">(3) </font></span><span style="line-height: 12pt; letter-spacing: 0.3pt"><font style="font-size: 7.5pt">然后，系统更新进程的页面表，这样一来，原来的虚拟地址现在就对应到内存中一个新的页面了。</font></span></font></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">系统在执行这些步骤之后，进程就可以访问它自己的副本了。第</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">17</font></span></font><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">章将进一步介绍存储器共享和写时复制。</font></font></span><span style="line-height: 19pt; letter-spacing: 0.3pt" lang="EN-US"></span></p>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">此外，在预订地址空间或调拨物理存储器时，不能使用</font></font></span><font style="font-size: 10.5pt"><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_WRITECOPY</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">或</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_EXECUTE_WRITECOPY</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">保护属性。这样做会导致调用</font></span><span class="SpellE"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">VirtualAlloc</font></span></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">失败，此时调用</font></span><span class="SpellE"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">GetLastError</font></span></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">会返回错误码</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">ERROR_INVALID_PARAMETER</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">。这两个属性是操作系统在映射</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">.exe</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">或</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">DLL</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">映像文件时用的。</font></font></span><span lang="EN-US"></span></span></p>
<h3 style="border-bottom: #aaa 1px solid; line-height: 17pt; padding-left: 10px; background: #f9fcfe; margin-left: 10px; word-break: break-all; margin-right: 10px"><font face="Arial"><span style="letter-spacing: 0.3pt" lang="EN-US"><font style="font-size: 10.5pt">13.6.2</font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"> </span></font></font><span style="letter-spacing: 0.3pt; font-family: "><font face="黑体"><font style="font-size: 10.5pt">一些特殊的访问保护属性标志</font></font></span><span style="font-family: " lang="EN-US"></span></h3>
<p style="line-height: 17pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">除了已经介绍过的保护属性之外，另外还有</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">3</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">个保护属性标志：</font></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_NOCACHE</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_WRITECOMBINE</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_GUARD</font></span></span><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">。使用这些标志时，只需将它们与除了</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_NOACCESS</font></span></span></font><span class="inparagraphemphasischar"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">之外的任何其他保护属性进行按位或操作即可。</font></font></span></span><span class="inparagraphemphasischar"><span style="font-family: ; mso-hansi-font-family: &#39;Times New Roman&#39;" lang="EN-US"></span></span></p>
<p style="line-height: 15.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">第一个保护属性标志</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_NOCACHE</font></span></font><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">，用来禁止对已调拨的页面进行缓存。该标志存在的主要目的是为了让需要操控内存缓冲区的驱动程序开发人员使用，不建议将该标志用于除此以外的其他用途。</font></font></span></p>
<p style="line-height: 17pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="41"><span style="line-height: 12pt; letter-spacing: 0.3pt" lang="EN-US"></span></p>
<p style="line-height: 15.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">第二个保护属性标志</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_WRITECOMBINE</font></span></font><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">也是给驱动程序开发人员用的。它允许把对单个设备的多次写操作组合在一起，以提高性能。</font></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"></span></p>
<p style="line-height: 15.1pt; margin-top: 7.8pt; margin-bottom: 14px; background: #f9fcfe; word-break: break-all" class="MsoNormal"><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">最后一个保护属性标志</font></font></span><font style="font-size: 10.5pt"><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">PAGE_GUARD</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">，使应用程序能够在页面中的任何一个字节被写入时得到通知。这个标志有一些巧妙的用法。</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">Windows</font></span><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">在创建线程<span class="GramE">栈</span>时会用到它。有关该标志的更多信息，请参阅第</font></span><span style="letter-spacing: 0.3pt" lang="EN-US"><font face="Arial">16</font></span></font><span style="letter-spacing: 0.3pt; font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">章。</font></font></span><span style="letter-spacing: 0.3pt" lang="EN-US"></span></p>
<p style="margin-bottom: 14px"><span lang="EN-US">         <br /></span><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">物理存储器的提交与回收</font></font></span></strong><font style="font-size: 10.5pt"><strong><span lang="EN-US">             </p>
<p></span></strong><font face="Arial"> 在地址空间中保留一个区域后，并不能直接对其进行使用，必须在把物理存储器提交给该区域后，才可以访问区域中的内存地址。在提交过程中，物理存储器是按页面边界和页面大小的块来进行提交的。若要为一个已保留的地址空间区域提交物理存储器，需要再次调用<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）函数，所不同的是在执行物理存储器的提交过程中需要指定<span class="SpellE"><span lang="EN-US">flAllocationType</span></span>参数为<span lang="EN-US">MEM_COMMIT</span>标志，使用的保护属性与保留区域时所用保护属性一致。在提交时，可以将物理存储器提交给整个保留区域，也可以进行部分提交，由<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）函数的<span class="SpellE"><span lang="EN-US">lpAddress</span></span>参数和<span class="SpellE"><span lang="EN-US">dwSize</span></span>参数指明要将物理存储器提交到何处以及要提交多少物理存储器。</font><span lang="EN-US">           <br /></span><font face="Arial">与保留区域的释放类似，当不再需要访问保留区域中被提交的物理存储器时，提交的物理存储器应得到及时的释放。该回收过程与保留区域的释放一样也是通过<span class="SpellE"><span lang="EN-US">VirtualFree</span></span>（）函数来完成的。在调用时为<span class="SpellE"><span lang="EN-US">VirtualFree</span></span>（）的<span class="SpellE"><span lang="EN-US">dwFreeType</span></span>参数指定<span lang="EN-US">MEM_DECOMMIT</span>标志，并在参数<span class="SpellE"><span lang="EN-US">lpAddress</span></span>和<span class="SpellE"><span lang="EN-US">dwSize</span></span>中传递用来标识要解除的第一个页面的内存地址和<span class="GramE">要</span>释放的字节数。此回收过程同样也是以页面为单位来进行的，将回收设定范围所涉及到的所有页面。下面这段代码演示了对先前保留区域的提交过程，并在使用完毕后将其回收：</font><span lang="EN-US">           </p>
<p><font face="Arial">// </font></span></font><font face="Arial"><font style="font-size: 10.5pt">在地址空间中保留一个区域</font></font></p>
<p style="margin-bottom: 14px"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">LPBYTE <span class="SpellE">bBuffer</span> = (LPBYTE<span class="GramE">)<span class="SpellE">VirtualAlloc</span></span>(NULL, 65536, MEM_RESERVE, PAGE_READWRITE);</font></font></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">提交物理存储器</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualAlloc</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">bBuffer</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">, 65536, MEM_COMMIT, PAGE_READWRITE);</font></span></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">……</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">回收提交的物理存储器</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualFree</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">bBuffer</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">, 65536, MEM_DECOMMIT);</font></span></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">释放已保留的区域</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualFree</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">bBuffer</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">, 0, MEM_RELEASE); </font></span></font></p>
<p style="margin-bottom: 14px"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt"> 由于未经提交的保留区域实际是无法使用的，因此在编程过程中允许通过一次<span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span>（）调用而完成对地址空间的区域保留及对保留区域的物理存储器的提交。相应的，回收、释放过程也可由一次<span class="SpellE"><span lang="EN-US">VirtualFree</span></span>（）调用来实现。上述代码可按此方法改写为：</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">在地址空间中保留一个区域并提交物理存储器</font></font></p>
<p style="margin-bottom: 14px"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">LPBYTE <span class="SpellE">bBuffer</span> = (LPBYTE<span class="GramE">)<span class="SpellE">VirtualAlloc</span></span>(NULL, 65536, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);</font></font></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><font style="font-size: 10.5pt">……</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">释放已保留的区域并回收提交的物理存储器</font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualFree</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">bBuffer</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">, 0, MEM_RELEASE | MEM_DECOMMIT);</font><span style="mso-spacerun: yes"><font style="font-size: 10.5pt"> </font></span></span></font></p>
<p style="margin-bottom: 14px"><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">页文件的使用</font></font></span></strong><font style="font-size: 10.5pt"><strong><span lang="EN-US">             </p>
<p></span></strong></font><font face="Arial"><font style="font-size: 10.5pt"> 在前面曾多次提到物理存储器，这里所说的<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">物理存储器</font></span>并不局限于计算机内存，还包括在磁盘空间上创建的页文件，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">其存储空间大小为计算机内存和页文件存储容量之<span class="GramE">和</span></font></span>。由于通常情况下磁盘存储空间要远大于内存的存储空间，因此页文件的使用对于应用程序而言相当于透明的增加了其所能使用的内存容量。在使用时，由操作系统和<span lang="EN-US">CPU</span>负责对页文件进行维护和协调。只有在应用程序需要时才临时将页文件中的数据加载到内存供应用程序访问之用，在使用完毕后再从内存<span class="GramE">交换回页文件</span>。</font></font></p>
<div style="border-bottom: windowtext 2.25pt double; border-left: medium none; padding-bottom: 1pt; padding-left: 0cm; padding-right: 0cm; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-element: para-border-div">
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font face="Arial"><font style="background-color: #ff0000; font-size: 10.5pt">进程中的线程在访问位于已提交物理存储器的保留区域的内存地址时，如果此地址指向的数据当前已存在于内存，<span lang="EN-US">CPU</span>将直接<span class="GramE">将进程</span>的虚拟地址映射为物理地址，并完成对数据的访问；如果此数据是存在于页文件中的，就要试图将此数据从页文件加载到内存。在进行此处理时，首先要检查内存中是否有可供使用的空闲页面，如果有就可以直接将数据加载到内存中的空闲页面，否则就要从内存中寻找一个暂不使用的可释放的页面并将数据加载到此页面。如果被释放页面中的数据仍为有效数据（即以后还会用到），就要先将此页面从内存写入到页文件。在数据加载到内存后，仍要在<span lang="EN-US">CPU</span>将虚拟地址映射为物理地址后方可实现对数据的访问。与对物理存储器中数据的访问有所不同，在运行可执行程序时并不进行程序代码和数据的从磁盘文件到页文件的复制过程，而是在确定了程序的代码及其数据的大小后，由系统直接将可执行程序的映像用作程序的保留地址空间区域。这样的处理方式大大缩短了程序的启动时间，并可减小页文件的尺寸。</font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm">
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/bacoo/accessmemory.jpg" /></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm">
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span style="letter-spacing: -0.05pt" lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt">上面提到的“数据是否在内存中”，我认为应该是判断系统缓存中是否有需要的页面。</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt">==========================================================================================</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt">对内存的管理</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 使用虚拟内存技术将能够对内存进行管理。对当前内存状态的动态信息可通过<span class="SpellE"><span lang="EN-US">GlobalMemoryStatus</span></span>（）函数来获取。<span class="SpellE"><span lang="EN-US">GlobalMemoryStatus</span></span>（）的函数原型为：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">VOID <span class="SpellE"><span class="GramE">GlobalMemoryStatus</span></span><span class="GramE">(</span>LPMEMORYSTATUS <span class="SpellE">lpBuffer</span>);</font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 其参数<span class="SpellE"><span lang="EN-US">lpBuffer</span></span>为一个指向内存状态结构<span lang="EN-US">MEMORYSTATUS</span>的指针，而且要预先对该结构对象的数据成员进行初始化。<span lang="EN-US">MEMORYSTATUS</span>结构定义如下：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">typedef</font></span></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> <span class="SpellE">struct</span> _MEMORYSTATUS { </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwLength</span>; // MEMORYSTATUS</span>结构大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwMemoryLoad</span>; // </span>已使用内存所占的百分比</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwTotalPhys</span>; // </span>物理存储器的总字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwAvailPhys</span>; // </span>空闲物理存储器的字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwTotalPageFile</span>; // </span>页文件包含的最大字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwAvailPageFile</span>; // </span>页文件可用字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwTotalVirtual</span>; // </span>用户模式分区大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwAvailVirtual</span>; // </span>用户模式分区中空闲内存大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">} MEMORYSTATUS, *LPMEMORYSTATUS; </font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt">下面这段代码通过设置一个定时器而每隔<span lang="EN-US">5</span>秒更新一次当前系统对内存的使用情况：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">设置定时器</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">SetTimer</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">0, 5000, NULL);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt">……</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">void</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> CSample22Dlg::OnTimer(UINT <span class="SpellE">nIDEvent</span>) </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">{</font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>获取当前内存使用状态</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> </font><span lang="EN-US"><font style="font-size: 10.5pt">MEMORYSTATUS <span class="SpellE"><span class="GramE">mst</span></span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span class="GramE"><span lang="EN-US">GlobalMemoryStatus</span></span></span><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">&amp;<span class="SpellE">mst</span>);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>已使用内存所占的百分比</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwMemoryLoad</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwMemoryLoad</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>物理存储器的总字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwAvailPhys</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwAvailPhys</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>空闲物理存储器的字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwAvailPageFile</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwAvailPageFile</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>页文件包含的最大字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwAvailVirtual</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwAvailVirtual</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>页文件可用字节数</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwTotalPageFile</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwTotalPageFile</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>用户模式分区大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwTotalPhys</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwTotalPhys</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>用户模式分区中空闲内存大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">m_dwTotalVirtual</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mst.dwTotalVirtual</span> / 1024;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">// </span>更新显示</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span class="GramE"><span lang="EN-US">UpdateData</span></span></span><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">FALSE);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span class="SpellE"><span lang="EN-US">CDialog::<span class="GramE">OnTimer</span></span></span><span class="GramE"><span lang="EN-US">(</span></span><span class="SpellE"><span lang="EN-US">nIDEvent</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">} </font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 对内存的管理除了对当前内存的使用状态信息进行获取外，还经常需要获取有关进程的虚拟地址空间的状态信息。可由<span class="SpellE"><span lang="EN-US">VirtualQuery</span></span>（）函数来进行查询，其原型声明如下：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">DWORD <span class="SpellE"><span class="GramE">VirtualQuery</span></span></font><span class="GramE"><font style="font-size: 10.5pt">(</font></span></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">LPCVOID <span class="SpellE">lpAddress</span>, // </span>内存地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">PMEMORY_BASIC_INFORMATION <span class="SpellE">lpBuffer</span>, // </span>指向内存信息结构的指针</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">dwLength</span> // </span>内存的大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">); </font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 其中<span class="SpellE"><span lang="EN-US">lpAddress</span></span>参数为要查询的虚拟内存地址，该值将被调整到最近的页边界处。当前计算机的页面大小可通过<span class="SpellE"><span lang="EN-US">GetSystemInfo</span></span>（）函数获取，该函数需要一个指向<span lang="EN-US">SYSTEM_INFO</span>结构的指针作为参数，获取到的系统信息将填充在该数据结构对象中。下面这段代码通过对<span class="SpellE"><span lang="EN-US">GetSystemInfo</span></span>（）的调用而获取了当前的系统信息：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">得到当前系统信息</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">GetSystemInfo</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">&amp;<span class="SpellE">m_sin</span>);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">位屏蔽，指明哪个<span lang="EN-US">CPU</span>是活动的</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwActiveProcessorMask</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.dwActiveProcessorMask</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">保留的地址空间区域的分配粒度</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwAllocationGranularity</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.dwAllocationGranularity</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">进程的可用地址空间的最小内存地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwMaxApplicationAddress</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = (DWORD<span class="GramE">)<span class="SpellE">m</span></span><span class="SpellE">_sin.lpMaximumApplicationAddress</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">进程的可用地址空间的最大内存地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwMinApplicationAddress</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = (DWORD<span class="GramE">)<span class="SpellE">m</span></span><span class="SpellE">_sin.lpMinimumApplicationAddress</span>; </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">计算机中<span lang="EN-US">CPU</span>的数目</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwNumberOfProcessors</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.dwNumberOfProcessors</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">页面大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwPageSize</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.dwPageSize</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">处理器类型</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwProcessorType</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.dwProcessorType</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">//</font></span><font style="font-size: 10.5pt">进一步细分处理器级别</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_wProcessorLevel</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.wProcessorLevel</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">系统处理器的结构</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_wProcessorArchitecture</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">m_sin.wProcessorArchitecture</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">更新显示</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">UpdateData</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">FALSE);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualQuery</font></span></span><font style="font-size: 10.5pt">（）的第二个参数<span class="SpellE"><span lang="EN-US">lpBuffer</span></span>为一个指向<span lang="EN-US">MEMORY_BASIC_INFORMATION</span>结构的指针。<span class="SpellE"><span lang="EN-US">VirtualQuery</span></span>（）如成功执行，该结构对象中将保存查询到的虚拟地址空间状态信息。<span lang="EN-US">MEMORY_BASIC_INFORMATION</span>结构的定义为：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">typedef</font></span></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> <span class="SpellE">struct</span> _MEMORY_BASIC_INFORMATION {</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">PVOID <span class="SpellE">BaseAddress</span>; // </span>保留区域的基地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">PVOID <span class="SpellE">AllocationBase</span>; // </span>分配的基地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">AllocationProtect</span>; // </span>初次保留时所设置的保护属性</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD <span class="SpellE">RegionSize</span>; // </span>区域大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD State; // </span>状态（提交、保留或空闲）</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD Protect; // </span>当前访问保护属性</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> <span lang="EN-US">DWORD Type; // </span>页面类型</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">} MEMORY_BASIC_INFORMATION;</font><span style="mso-spacerun: yes"><font style="font-size: 10.5pt"> </font></span></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 通过<span class="SpellE"><span lang="EN-US">VirtualQuery</span></span>（）函数对由<span class="SpellE"><span lang="EN-US">lpAddress</span></span>和<span class="SpellE"><span lang="EN-US">dwLength</span></span>参数指定的虚拟地址空间区域的查询而获取得到的相关状态信息：</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">更新显示</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">UpdateData</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">TRUE);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">虚拟地址空间状态结构</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">MEMORY_BASIC_INFORMATION <span class="SpellE">mbi</span>;</font></font></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">查询指定虚拟地址空间的状态信息</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">VirtualQuery</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">(LPCVOID)<span class="SpellE">m_dwAddress</span>, &amp;<span class="SpellE">mbi</span>, 1024);</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">保留区域的基地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwBaseAddress</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = (DWORD<span class="GramE">)<span class="SpellE">mbi.BaseAddress</span></span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">分配的基地址</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwAllocateBase</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = (DWORD<span class="GramE">)<span class="SpellE">mbi.AllocationBase</span></span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">初次保留时所设置的保护属性</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwAllocateProtect</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mbi.AllocationProtect</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">区域大小</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwRegionSize</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mbi.RegionSize</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">状态（提交、保留或空闲）</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwState</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mbi.State</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">当前访问保护属性</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwProtect</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mbi.Protect</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">页面类型</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span lang="EN-US"><font style="font-size: 10.5pt">m_dwType</font></span></span><span lang="EN-US"><font style="font-size: 10.5pt"> = <span class="SpellE">mbi.Type</span>;</font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span lang="EN-US"><font style="font-size: 10.5pt">// </font></span><font style="font-size: 10.5pt">更新显示</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">UpdateData</font></span></span></span><font style="font-size: 10.5pt"><span class="GramE"><span lang="EN-US">(</span></span></font><span lang="EN-US"><font style="font-size: 10.5pt">FALSE); </font></span></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 小结</font></font></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span lang="EN-US"></span></p>
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><font face="Arial"><font style="font-size: 10.5pt"> 本文主要对内存管理中的虚拟内存技术的基本原理、使用方法和对内存的管理等进行了介绍。通过本文将能够掌握虚拟内存的一般使用方法，与之相关的内存管理技术还包括内存文件映射和堆管理等技术，读者可参阅相关文章。这几种内存管理技术同属<span lang="EN-US">Windows</span>编程中的高级技术，在应用程序中适当使用将有助于程序性能的提高。本文所述程序在<span lang="EN-US">Windows 2000 Professional</span>下由<span lang="EN-US">Microsoft <span class="SpellE">Viusual</span> C++ 6.0</span>编译通过。</font></font></p>
</p></div>
<p style="margin-bottom: 14px" class="MsoNormal"><strong><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">进程的虚拟地址空间</font></font></span></strong><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt"> </font></font></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><span><font style="font-size: 10pt">每个进程都被赋予它自己的虚拟地址空间。对于<span lang="EN-US">3 2</span>位进程来说，这个地址空间是<span lang="EN-US">4 G</span><span lang="EN-US"> B</span>，因为<span lang="EN-US">3 2</span>位指针可以拥有从<span lang="EN-US">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></span>至<span lang="EN-US">0 x F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span></span>之间的任何一个值。这使得一个指针能够拥有<span lang="EN-US">4 294 967 296</span>个值中的一个值，它覆盖了一个进程的<span lang="EN-US">4 G</span><span lang="EN-US"> B</span>虚拟空间的范围。对于<span lang="EN-US">6 4</span>位进程来说，这个地址空间是<span lang="EN-US">1 6 E B</span>（<span lang="EN-US">1 01 8</span>字节），因为<span lang="EN-US">6 4</span>位指针可以拥有从<span lang="EN-US">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></span>至<span lang="EN-US">0 x F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span></span>之间的任何值。这使得一个指针可以拥有<span lang="EN-US">18 446 744 073 709 551 616</span>个值中的一个值，它覆盖了一个进程的<span lang="EN-US">1 6 E B</span>虚拟空间的范围。这是相当大的一个范围。</font></span><font style="font-size: 10.5pt"> </font></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span><font style="font-size: 10pt">由于每个进程可以接收它自己的私有的地址空间，因此当进程中的一个线程正在运行时，该线程可以访问只属于它的进程的内存。属于所有其他进程的内存则隐藏着，并且不能被正在运行的线程访问。</font></span><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span><font style="font-size: 10pt">注意在<span lang="EN-US">Windows 2000</span>中，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">属于操作系统本身的内存也是隐藏的，正在运行的线程无法访问</font></span>。这意味着线程常常不能访问操作系统的数据。<span lang="EN-US">Windows 98</span>中，属于操作系统的内存是不隐藏的，正在运行的线程可以访问。因此，正在运行的线程常常可以访问操作系统的数据，也可以破坏操作系统（从而有可能导致操作系统崩溃）。在<span lang="EN-US">Windows 98</span>中，一个进程的线程不可能访问属于另一个进程的内存。</font></span><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="margin-bottom: 14px"><font face="Arial"><span><font style="font-size: 10pt">前面说过，每个进程有它自己的私有地址空间。进程<span lang="EN-US">A</span>可能有一个存放在它的地址空间中的数据结构，地址是<span lang="EN-US">0 x 1 2 3 4 5 6 7 8</span>，<span class="GramE">而进程</span><span lang="EN-US">B</span>则有一个完全不同的数据结构存放在它的地址空间中，地址是<span lang="EN-US">0 x 1 2 3 4 5 6 7 8</span>。当进程<span lang="EN-US">A</span>中运行的线程访问地址为<span lang="EN-US">0 x 1 2 3 4 5 6 7 8</span>的内存时，这些线程访问的是进程<span lang="EN-US">A</span>的数据结构。当进程<span lang="EN-US">B</span>中运行的线程访问地址为<span lang="EN-US">0 x 1 2 3 4 5 6 7 8</span>的内存时，这些线程访问的是进程<span lang="EN-US">B</span>的数据结构。进程<span lang="EN-US">A</span>中运行的线程不能访问进程<span lang="EN-US">B</span>的地址空间中的数据结构。反之亦然。</font></span><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">当你因为拥有如此大的地址空间可以用于应用程序而兴高采烈之前，记住，这是个虚拟地址空间，不是物理地址空间。该地址空间只是内存地址的一个范围。在你能够成功地访问数据而不会出现违规访问之前，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">必须赋予物理存储器</font></span>，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">或者将物理存储器映射到各个部分的地址空间</font></span>。本章后面将要具体介绍这是如何操作的。</font></font></span></p>
<p style="margin-bottom: 14px"><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">虚拟地址空间如何分区</font></font></span></strong></p>
<p style="margin-bottom: 14px"><span style="color: "><font face="Arial"><font style="font-size: 10pt">每个进程的虚拟地址空间都要划分成各个分区。地址空间的分区是根据操作系统的基本实现方法来进行的。不同的<span class="SpellE"><span lang="EN-US">Wi</span></span><span lang="EN-US"> n d o w s</span>内核，其分区也略有不同。表<span lang="EN-US"> 1</span>显示了每种平台是如何<span class="GramE">对进程</span>的地址空间进行分区的。</font></font></span></p>
<p style="margin-bottom: 14px" align="center"><font face="Arial"><font style="font-size: 10.5pt">表<span lang="EN-US">1 </span>进程的地址空间如何分区</font><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<div align="center">
<table style="border-bottom: olive 1.5pt outset; text-align: left; border-left: olive 1.5pt outset; line-height: normal; border-top: olive 1.5pt outset; border-right: olive 1.5pt outset; mso-padding-alt: 4.5pt 4.5pt 4.5pt 4.5pt; mso-cellspacing: .7pt" class="MsoNormalTable" border="1" cellspacing="1" cellpadding="0" width="100%">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal" align="center"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">分区</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal" align="center"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">32</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows 2000(x86</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span lang="EN-US"><font face="Arial">Alpha</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">处理器</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">)</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal" align="center"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">32</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows 2000(x86w/3GB</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">用户方式</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">)</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal" align="center"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">64</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows 2000(Alpha</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span lang="EN-US"><font face="Arial">IA-64</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">处理器</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">)</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal" align="center"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Windows 98</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><font style="background-color: #ff0000"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">N U L <span class="SpellE">L</span></font></font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">指针分配的分区</font></font></span></font><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span><span style="mso-spacerun: yes"> </span></font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">——</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> F <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> F <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0x00000000 00000000 0x00000000 0000FFFF</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> F <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">DOS/16</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">应用程序兼容分区</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> 1 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x 0 <span class="SpellE">0</span> 3 F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 3">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="background-color: #ff0000; font-size: 10.5pt">用户方式</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="mso-ansi-language: de" lang="DE"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 0 0 1 0 0 0 0</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-ansi-language: de"><font face="宋体">——</font></span><span style="mso-ansi-language: de"><font face="Arial"> <span lang="DE">0 x 7 F F E F F F F&lt;</span></font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-ansi-language: de"><font face="宋体">将近</font></span></font><font face="Arial"><font style="font-size: 10.5pt"><span style="mso-ansi-language: de" lang="DE">2G</span></font><span style="mso-ansi-language: de" lang="DE"><font style="font-size: 10.5pt">&gt;</font></span></font><span style="font-family: ; mso-bidi-font-family: 宋体; mso-ansi-language: de" lang="DE"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="mso-ansi-language: de" lang="DE"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 0 0 1 0 0 0 0 0 x B F F E F F F F F</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体; mso-ansi-language: de" lang="DE"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0x00000000 00010000 0x000003FF FFFEFFFF</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> 4 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x 7 F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><font style="background-color: #ff0000"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">64-KB</font></font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">禁止进入分区</font></font></span></font><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 7 F <span class="SpellE">F</span> <span class="SpellE">F</span> 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">——</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0x7FFF FFFF</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x B F <span class="SpellE">F</span> <span class="SpellE">F</span> 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">——</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x B F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" valign="top" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> 3 F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">——</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> 3 F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 5">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">共享内存映射</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">无</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 8 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> </font><span class="SpellE"><font style="font-size: 10.5pt">0</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 6; mso-yfti-lastrow: yes">
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">文件</font></font></span><font style="font-size: 10.5pt"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">(MMF)</font></span></font><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">内核方式</font></font></span></font><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="23.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x 8 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> </font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">——</font></span><span lang="EN-US"><font face="Arial"> 0 x F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span>&lt;</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">共</font></span></font><font face="Arial"><font style="font-size: 10.5pt"><span lang="EN-US">2G</span></font><span lang="EN-US"><font style="font-size: 10.5pt">&gt;</font></span></font><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="16.36%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x C 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0x00000400 00000000 0xFFFFFFFFF FFFFFFF</font></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
<td style="border-bottom: olive 1pt inset; border-left: olive 1pt inset; padding-bottom: 4.5pt; padding-left: 4.5pt; padding-right: 4.5pt; border-top: olive 1pt inset; border-right: olive 1pt inset; padding-top: 4.5pt; mso-border-alt: inset olive .75pt" width="19.76%">
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">0 x B F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> 0 x C 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> x F <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> <span class="SpellE">F</span> </font><span class="SpellE"><font style="font-size: 10.5pt">F</font></span></font></span><span style="font-family: ; mso-bidi-font-family: 宋体" lang="EN-US"></span></p>
</td>
</tr>
</tbody>
</table></div>
<p style="margin-bottom: 14px" class="MsoNormal" align="left"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">1. NULL</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">指针分区是</font></span><span lang="EN-US"><font face="Arial">NULL</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">指针的地址范围。</font></span><span lang="EN-US">           <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">对这个区域的读写企图都将引发访问违规。</font></span><span lang="EN-US"><font face="Arial">              <br />2. DOS/WIN16</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">分区是</font></span><span lang="EN-US"><font face="Arial">98</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中专门用于</font></span><span lang="EN-US"><font face="Arial">16</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位的</font></span><span lang="EN-US">           <br /><font face="Arial">DOS</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和</font></span><span lang="EN-US"><font face="Arial">windows</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">程序运行的空间，所有的</font></span><span lang="EN-US"><font face="Arial">16</font>            <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位程序将共享这个</font></span><span lang="EN-US"><font face="Arial">4M</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的空间。</font></span><span lang="EN-US"><font face="Arial">Win2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中不</font></span><span lang="EN-US">           <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">存在这个分区，</font></span><span lang="EN-US"><font face="Arial">16</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位程序也会拥有自己独立的虚拟地址空间。有的文章中称</font></span><span lang="EN-US"><font face="Arial">win2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中不能运行</font></span><span lang="EN-US"><font face="Arial">16</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位程序，是不确切的。</font></span><span lang="EN-US"><font face="Arial">              <br />3.</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">用户分区是进程的私有领域，</font></span><span lang="EN-US"><font face="Arial">Win2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中，程序的可执行代码和其它用户模块均加载在这里，内存映射文件也会加载在这里。</font></span><span lang="EN-US"><font face="Arial">Win98</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中的系统共享</font></span><span lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">和内存映射文件则加载在共享分区中。</font></span><span lang="EN-US"><font face="Arial">              <br />4.</font></span><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">禁止访问分区只有在</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">win2000</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">中有。这个分区是用户分区和内核分区之间的一个隔离带，目的是为了防止用户程序违规访问内核分区。</font></span></font><span lang="EN-US"><font face="Arial">              <br />5. MMF</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">分区只有</font></span><span lang="EN-US"><font face="Arial">win98</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中有，所有的内存映射文件和系统共享</font></span><span lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">将加载在这个地址。而</font></span><span lang="EN-US"><font face="Arial">2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中则将其加载到用户分区。</font></span><span lang="EN-US"><font face="Arial">              <br />6. </font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">内核方式分区对用户的程序来说是禁止访问的，操作系统的代码在此。内核对象也驻留在此。</font></span><span lang="EN-US">           <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">另外要说明的是，</font></span><span lang="EN-US"><font face="Arial">win98</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中对于内核分区本也应该提供保护的，但遗憾的是并没有做到，因而</font></span><span lang="EN-US"><font face="Arial">98</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中程序可以访问内核分区的地址空间。</font></span><span lang="EN-US">           <br /></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">对于用户分区，又可以细分成若干区域。（这些区域具体会在第四阶段详细剖析。因为这部分内容牵扯到</font></span><span lang="EN-US"><font face="Arial">PE</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">文件结构</font></span><span lang="EN-US"><font face="Arial">,</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">只有学习并理解了</font></span><span lang="EN-US"><font face="Arial">PE</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">文件结构后，才能理解这部分内容，为了便于后面的讲解，在此讲这部分区域先大致分为</font></span><span lang="EN-US"><font face="Arial">4</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">块：）</font></font></span><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal" align="left"><span lang="EN-US"><font face="Arial"><font style="font-size: 10pt">3 2</font></font></span><font style="font-size: 10pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows 2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的内核与</font></span><span lang="EN-US"><font face="Arial">6 4</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位</font></span><span lang="EN-US"><font face="Arial">Windows 2000</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的内核拥有大体相同的分区，差别在于分区的大小和位置有所不同。另一方面，可以看到</font></span><span lang="EN-US"><font face="Arial">Windows 98</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10pt">下的分区有着很大的不同。下面让我们看一下系统是如何使用每一个分区的。</font></font></span><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px"><font face="宋体"><strong><span style="font-family: " lang="EN-US"><font style="font-size: 10.5pt">NULL</font></span></strong><strong><span style="font-family: "><font style="font-size: 10.5pt">指针分配的分区<span lang="EN-US">—</span>适用于<span lang="EN-US">Windows 2000</span>和</font><span lang="EN-US"><font style="font-size: 10.5pt">Windows 98</font></span></span></strong></font></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">进程地址空间的这个分区的设置是为了帮助程序员掌握<span lang="EN-US">N U L <span class="SpellE">L</span></span>指针的分配情况。</font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000; font-size: 10pt">如果你的进程中的线程试图读取该分区的地址空间的数据，或者将数据写入该分区的地址空间，那么<span lang="EN-US">C P U</span>就会引发一个访问违规。保护这个分区是极其有用的，它可以帮助你发现<span lang="EN-US">N U L <span class="SpellE">L</span></span>指针的分配情况。</font></span></font></span></p>
<p style="margin-bottom: 14px"><font face="Arial"><span lang="EN-US"><font style="font-size: 10pt">C / C + +</font></span><span><font style="font-size: 10pt">程序中常常不进行严格的错误检查。例如，下面这个代码就没有进行任何错误检查：</font></span><span lang="EN-US"><font style="font-size: 10.5pt"> </font></span></font></p>
<pre style="line-height: 12.95pt; margin: 0px 0px 0px 22px; background: #d7d7d7"><span class="SpellE"><span class="GramE"><span lang="EN-US"><font style="font-size: 10.5pt">int</font></span></span></span><span lang="EN-US"><font style="font-size: 10.5pt">* <span class="SpellE">pnSomeInteger</span> = (<span class="SpellE">int</span>*) <span class="SpellE">malloc</span>(<span class="SpellE">sizeof</span>(<span class="SpellE">int</span>));</font></span></pre>
<pre style="line-height: 12.95pt; margin: 0px 0px 0px 22px; background: #d7d7d7"><span lang="EN-US"><font style="font-size: 10.5pt">*<span class="SpellE">pnSomeInteger</span> = 5;</font></span></pre>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">如果<span lang="EN-US">m a l <span class="SpellE">l</span> o c</span>不能找到足够的内存来满足需要，它就返回<span lang="EN-US">N U L <span class="SpellE">L</span></span>。但是，该代码并不检查这种可能性，它认为地址的分配已经取得成功，并且开始访问<span lang="EN-US">0 x 0 <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span> <span class="SpellE">0</span></span>地址的内存。由于这个分区的地址空间是禁止进入的，因此就会发生内存访问违规现象，同时该进程将终止运行。这个特性有助于编程员发现应用程序中的错误。</font></font></span></p>
<p style="margin-bottom: 14px"><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">用户方式分区<span lang="EN-US">—</span>适用于<span lang="EN-US">Windows 2000</span>和</font><span lang="EN-US"><font style="font-size: 10.5pt">Windows 98</font></span></font></span></strong></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">这个分区是进程的私有（非共享）地址空间所在的地方。<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">一个进程不能读取、写入、或者以任何方式访问驻留在该分区中的另一个进程的数据。对于所有应用程序来说，该分区是维护进程的大部分数据的地方。由于每个进程可以得到它自己的私有的、非共享分区，以便存放它的数据，</font></span>因此，应用程序不太可能被其他应用程序所破坏，这使得整个系统更加健壮。</font></font></span></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">在<span lang="EN-US">Windows 2000</span>中，所有的<span lang="EN-US">. e x e</span>和<span lang="EN-US">D L <span class="SpellE">L</span></span>模块均加载这个分区。每个进程可以将这些<span lang="EN-US">D L <span class="SpellE">L</span></span>加载到该分区的不同地址中（不过这种可能性很小）。</font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000; font-size: 10pt">系统还可以在这个分区中映射该进程可以访问的所有内存映射文件</font></span></font><span lang="EN-US"></span></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">共享的</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">MMF</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">分区</font></span><span lang="EN-US"><font face="Arial">—</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">仅适用于</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Windows 98 </font></font></span></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">这个<span lang="EN-US">1 G</span><span lang="EN-US"> B</span>分区是系统用来存放所有<span lang="EN-US">3 2</span>位进程共享数据的地方。例如，系统的动态链接库<span lang="EN-US">K e r n e l 3 2 . d l <span class="SpellE">l</span></span>、<span lang="EN-US">A d v A P I 3 2 . d l <span class="SpellE">l</span></span>、<span lang="EN-US">U s e r 3 2 . d l <span class="SpellE">l</span></span>和<span lang="EN-US">G D I 3 2 . d l <span class="SpellE">l</span></span>等，全部存放在这个地址空间分区中，因此，所有<span lang="EN-US">3 2</span>位进程都能很容易同时访问它们。系统还为每个进程将<span lang="EN-US">D L <span class="SpellE">L</span></span>加载相同的内存地址。此外，系统将所有内存映射文件映射到这个分区中。</font></font></span></p>
<p style="margin-bottom: 14px"><strong><span style="font-family: "><font face="宋体"><font style="font-size: 10.5pt">物理存储器与页文件</font></font></span></strong></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">在较老的操作系统中，物理存储器被视为计算机拥有的<span lang="EN-US">R A M</span>的容量。换句话说，如果计算机拥有<span lang="EN-US">1 6 M B</span>的<span lang="EN-US">R A M</span>，那么加载和运行的应用程序最多可以使用<span lang="EN-US">1 6 M B</span>的<span lang="EN-US">R A M</span>。今天的操作系统能够使得磁盘空间看上去就像内存一样。磁盘上的文件通常称为页文件，它包含了可供所有进程使用的虚拟内存</font></font></span></p>
<p style="margin-bottom: 14px"><span style="color: "><font face="Arial"><font style="font-size: 10pt">当然，若要使虚拟内存能够运行，需要得到<span lang="EN-US">C P U</span>本身的大量帮助。当一个线程试图访问一个字节的内存时，<span lang="EN-US"> C P U</span>必须知道这个字节是在<span lang="EN-US">R A M</span>中还是在磁盘上。</font></font></span></p>
<p style="margin-bottom: 14px"><span style="color: "><font face="Arial"><font style="font-size: 10pt">从应用程序的角度来看，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">页文件透明地增加了应用程序能够使用的<span lang="EN-US">R A M</span>（即内存）的数量</font></span>。如果计算机拥有<span lang="EN-US">6 4 M B</span>的<span lang="EN-US">R A M</span>，同时在硬盘上有一个<span lang="EN-US">100 MB</span>的页文件，那么运行的应用程序就认为计算机总共拥有<span lang="EN-US">1 6 4 M B</span>的<span lang="EN-US">R A M</span>。</font></font></span></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">实际上并不拥有<span lang="EN-US">1 6 4 M B</span>的<span lang="EN-US">R A M</span>。相反，操作系统与<span lang="EN-US">C P U</span>相协调，共同将<span lang="EN-US">R A M</span>的各个部分保存到页文件中，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">当运行的应用程序需要时，再将页文件的各个部分重新加载到<span lang="EN-US">R A M</span></font></span>。由于页文件增加了应用程序可以使用的<span lang="EN-US">R A M</span>的容量，因此页文件的使用是视情况而定的。如果没有页文件，那么系统就认为只有较少的<span lang="EN-US">R A M</span>可供应用程序使用。但是，我们鼓励用户使用页文件，这样他们就能够运行更多的应用程序，并且这些应用程序能够对更大的数据集进行操作。<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">最好将物理存储器视为存储在磁盘驱动器（通常是硬盘驱动器）上的页文件中的数据。这样，当一个应用程序通过调用<span lang="EN-US">Vi r t u a l A l <span class="SpellE">l</span> o c</span>函数，将物理存储器提交给地址空间的一个区域时，地址空间实际上是从硬盘上的一个文件中进行分配的。</font></span>系统的页文件的大小是确定有多少物理存储器可供应用程序使用时应该考虑的最重要的因素，<span lang="EN-US"> R A M</span>的容量则影响非常小。</font></font></span></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">第一种情况中，线程试图访问的数据是在<span lang="EN-US">R A M</span>中。在这种情况下，<span lang="EN-US"> C P U</span>将数据的虚拟内存地址映射到内存的物理地址中，然后执行需要的访问。线程试图访问的数据不在<span lang="EN-US">R A M</span>中，而是存放在页文件中的某个地方。这时，试图访问就称为页面失效，<span lang="EN-US"> C P U</span>将把试图进行的访问通知操作系统。这时操作系统就寻找<span lang="EN-US">R A M</span>中的一个内存空页。如果找不到空页，系统必须释放一个空页。如果一个页面尚未被修改，系统就可以释放该页面。但是，如果系统需要释放一个已经修改的页面，那么它必须首先将该页面从<span lang="EN-US">R A M</span>拷贝到页交换文件中，然后系统进入该页文件，找出需要访问的数据块，并将数据加载到空闲的内存页面。然后，操作系统更新它的用于指明数据的虚拟内存地址现在已经映射到<span lang="EN-US">R A M</span>中的相应的物理存储器地址中的表。这时<span lang="EN-US">C P U</span>重新运行生成初始页面失效的指令，但是这次<span lang="EN-US">C P U</span>能够将虚拟内存地址映射到一个物理<span lang="EN-US">R A M</span>地址，并访问该数据块。</font></font></span></p>
<p style="margin-bottom: 14px"><span><font face="Arial"><font style="font-size: 10pt">当阅读了上一节后，你必定会认为，如果同时运行许多文件的话，页文件就可能变得非常大，而且你会认为，每当你运行一个程序时，系统必须<span class="GramE">为进程</span>的代码和数据保留地址空间的一些区域，将物理存储器提交给这些区域，然后将代码和数据从硬盘上的程序文件拷贝到页文件中已提交的物理存储器中。</font></font></span></p>
<div style="border-bottom: windowtext 2.25pt double; border-left: medium none; padding-bottom: 1pt; padding-left: 0cm; padding-right: 0cm; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-element: para-border-div">
<p style="border-bottom: medium none; border-left: medium none; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm; margin-bottom: 14px; border-top: medium none; border-right: medium none; padding-top: 0cm; mso-border-bottom-alt: double windowtext 2.25pt; mso-padding-alt: 0cm 0cm 1.0pt 0cm"><span><font face="Arial"><font style="font-size: 10pt">实际上系统并不进行上面所说的这些操作。如果它进行这些操作的话，就要花费很长的时间来加载程序并启动它运行。相反，当启动一个应用程序的时候，系统将打开该应用程序的<span lang="EN-US">. e x e</span>文件，确定该应用程序的代码和数据的大小。<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">然后系统要保留一个地址空间的区域，并指明与该区域相关联的物理存储器是在<span lang="EN-US">. e x e</span>文件本身中</font></span>。</font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000; font-size: 10pt">即系统并不是从页文件中分配地址空间，而是将<span lang="EN-US">. e x e</span>文件的实际内容即映像用作程序的保留地址空间区域。当然，这使应用程序的加载非常迅速，<span class="GramE">并使页文件</span>能够保持得非常小</font></span></font></span></p>
</p></div>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">一、开始之前，让我们来了解一下</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Windows</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">中内存管理的一些知识</font></span></font><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">:</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">1. </font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">机器的物理内存由两部分组成。一部分为机器的主存</font></span><span lang="EN-US"><font face="Arial">RAM</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">，也就是我们内存条的大小；另一部分为虚拟内存，它就在机器的硬盘上，以页文件的形式存在。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">2. </font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">每个进程都有自己的虚拟地址空间，对于具有</font></span><span lang="EN-US"><font face="Arial">32</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">位寻址能力的机器来说，这个虚拟空间的大小为</font></span><span lang="EN-US"><font face="Arial">4GB</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">。现在我们使用的机器就是</font></span><span lang="EN-US"><font face="Arial">4GB</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">3. </font></font></span><font style="font-size: 10.5pt"><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">进程的</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">4GB</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">虚拟地址空间又可以分成几个部分，其中进程真正私有的空间少于</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">2GB</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">（这段地址空间被称作“用户方式分区”），其余的</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">2GB</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">多空间都是给操作系统的，且这部分空间被所有的进程共享。</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">（参考</font></span><span lang="EN-US"><font face="Arial">Windows</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">核心编程</font></span><span lang="EN-US"><font face="Arial">Chapter 13</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">）</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">4. </font></font></span><font face="宋体"><font style="background-color: #ff0000"><font style="font-size: 10.5pt"><span class="GramE"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red">为进程</span></span></font><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font style="font-size: 10.5pt">“分配内存”，这个概念可以细化：“保留<span class="GramE">一</span>段地址空间”，“提交一段内存空间”，“将内存空间映射到主存”。在程序中我们通常所访问的地址都必须是进程地址空间中被保留和提交的那段地址空间。</font></span></font></font></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">4.1 </font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“保留<span class="GramE">一</span>段地址空间”：即<span class="GramE">从进程</span>的</font></span><span lang="EN-US"><font face="Arial">4GB</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">地址空间中保留<span class="GramE">一</span>段地址空间，这个过程通过</font></span><span class="SpellE"><span lang="EN-US"><font face="Arial">VirtualAlloc</font></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">函数完成，并把分配类型参数设置为</font></span><span lang="EN-US"><font face="Arial">MEM_RESERVE</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">。这段空间的起始地址必须是系统分配粒度的整数<span class="GramE">倍</span>，大小必须是系统页面大小的整数<span class="GramE">倍</span>。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">4.2 </font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“提交一段内存空间”：即<span class="GramE">为进程</span>已保留的地址空间映射机器的物理内存，这里要特别注意，<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">所谓物理内存一般并不是机器的主存，而只是机器的虚拟内存</font></span>。这个过程同样又</font></span><span class="SpellE"><span lang="EN-US"><font face="Arial">VirtualAlloc</font></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">完成，只是把分配类型参数设置为</font></span><span lang="EN-US"><font face="Arial">MEM_COMMIT</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">。这段空间的起始地址和大小都必须是页面大小的整数<span class="GramE">倍</span>。这样进程的对应被提交的区域就被映射到机器的虚拟内存上。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">4.3 </font></font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="background-color: #ff0000; font-size: 10.5pt">“将内存空间映射到主存”：这点很重要，操作系统总是只有在进程提交的页面被访问时才将相应的页面加载到主存中，同时修改进程对应页面的地址空间映射。这时，进程的地址空间中的对应区域才和机器上的主存对应起来。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Virtual Size</font></font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了当<span class="GramE">前进程</span>申请成功的其虚拟地址空间的总的空间大小，包括</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">DLL/EXE</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">占用的地址和通过</font></span><font face="Arial"><span class="SpellE"><span lang="EN-US">VirtualAlloc</span></span><span lang="EN-US"> API Reserve</span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的</font></span><span lang="EN-US"><font face="Arial">Memory Space</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">数量。请注意，该指标包括保留的地址空间。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Private Bytes</font></font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了进程用户方式分区地址空间中已提交的总的空间大小。无论是直接调用</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">API</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">申请的内存，被</font></span><span lang="EN-US"><font face="Arial">Heap Manager</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">申请的内存，或者是</font></span><span lang="EN-US"><font face="Arial">CLR </font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">的</font></span><span lang="EN-US"><font face="Arial">managed heap</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">，都算在里面。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Working Set</font></font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了所有映射<span class="GramE">到进程</span>虚拟地址空间的机器主存的大小，它不仅仅是用户方式分区部分的映射，而是整个进程地址空间的映射。即它同时包括内核方式分区中映射到机器主存的部分。由</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">4.3</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">可知，在用户方式分区部分只有在进程提交的页面被访问时才将相应的页面加载到主存中。而对于该部分的大小总是系统页面大小的整数<span class="GramE">倍</span>。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">这里有一个问题，随着进程的不断运行，进程被访问的页面将可能不断增加，这是否意味着“</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”的大小会不断的累加呢？显然不是。在程序运行过程中影响“</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”的因素包括：</font></span><span lang="EN-US"><font face="Arial">(1) </font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">机器可用主存的大小</font></span><span lang="EN-US"><font face="Arial"> (2) </font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">进程本身“</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”的大小范围。当机器的可用主存小于一定值时，系统会释放一些老的最近没有被访问的页面，把这些页面通过交换文件交换到机器的虚拟内存中；当</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">的大小大于该进程所设置的最大值时，同样会把一些老的页面交换到机器的虚拟内存中。当这些页面下次再被访问时，它们才加载到主存。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">由上可知，<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“一定比”</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Private Bytes</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“小，因为它只是”</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Private Bytes</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“对应的地址空间中被加载到主存的那部分</font></span></font></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“</font></font></span><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">Page Faults”</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标和<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span><font face="宋体"><span class="GramE"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;">“</span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;">密切相关，当进程访问某个页面，而这个页面却不在主存中时，就要发生一次<span class="GramE">“</span></span></font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font style="background-color: #ff0000" face="Arial">Page Fault</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“，即进程访问非”</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“中的页面时，发生一次”</font></span><span lang="EN-US"><font face="Arial">Page Fault</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“，同时系统将对应页面加载到主存中。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">接下来的三个指标是对<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“的细化：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">”</font></font></span><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">WS Private“</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了进程<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“中被该进程所独享的空间大小。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">&quot;WS Shareable&quot;</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了进程<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“中能与别的进程共享的空间大小</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">”</font></font></span><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">WS Shared“</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">该指标记录了进程<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“中已经与别的进程共享的空间大小</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">”</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">WS Shareable</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“和”</font></span><span lang="EN-US"><font face="Arial">WS Shared</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“两个指标<span class="GramE">乍</span>一看令人感到疑惑，因为既然”</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“属于”</font></span><span lang="EN-US"><font face="Arial">Private Bytes</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“中的一部分，而”</font></span><span lang="EN-US"><font face="Arial">Private Bytes</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“是进程私有的，为什么会有”</font></span><span lang="EN-US"><font face="Arial">WS Shareable</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“和”</font></span><span lang="EN-US"><font face="Arial">WS Shared</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“这两项呢？</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">认真一想，其实很容易理解，比如两个进程都需要同一个</font></font></span><font style="font-size: 10.5pt"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">的支持，所以在进程运行过程中，这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">被映射到了两个进程的地址空间中，如果这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">的大小为</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">4K</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">，在两个进程中都要提交</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">4K</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">的虚拟地址空间来映射这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">。当第一个进程访问了这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">时，这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">被加载到机器主存中，这时，第二个进程也要访问该</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">，这时，系统就不会再加载一遍该</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">了，因为这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">已经在主存中了。当然上面所说的访问仅仅是读取的操作，如果这时候某个进程要修改</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">对应这段地址中的某个单元时，这时，系统必须为第二个进程分配另外的新页面，并把要修改位置对应的页面拷贝的这个新页面，同时，第二个进程中的这个</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span></font><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">被映射到这个新页面上。</font></font></span></font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><span style="mso-spacerun: yes"></span></span><font style="background-color: #ff0000"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">上面的分析中，</font></font></span><font style="font-size: 10.5pt"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">DLL</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">对应的</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">4K</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">的内存在第一个进程中便是<span class="GramE">”</span></font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">WS Shareable</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“。另外，内核方式分区中的所有代码都是被所有进程共享的，只要一个进程访问了这些页面，则在所有的进程的<span class="GramE">”</span></font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体"><font style="font-size: 10.5pt">“中都能体现。</font></font></span></font></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">三、下面我们来讨论一下这些内存指标与进程内存消耗之间的关系</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">在计算机更新换代不断加速的今天，我们往往很少关注程序对内存的消耗，除非程序的内存消耗超出了我们的忍受范围——大量的泄漏、运行速度下降等。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">那么，当我们在<span class="GramE">测进程</span>的内存使用量时，到底应该使用哪个指标能更好的反应程序的内存消耗呢？<span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000">由于</font></span></font></font></span><font style="font-size: 10.5pt"><font style="background-color: #ff0000"><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Windows</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">自带的</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Task Manager</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">中的<span class="GramE">”</span></font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Memory Usage</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“所对应的指标就是”</font></span><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red" lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font face="宋体">“</font></span></font></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">，所以大部分人认为该指标能够很好的反应进程的内存使用量。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">在得出结论之前，让我们来分析一下以上的这些指标：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">就从<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“开始吧。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">”</font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">进程中被加载到机器主存的所有页面大小的<span class="GramE">和</span>。它可细分为<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">WS Shareable</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“和”</font></span><span lang="EN-US"><font face="Arial">WS Shared</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“。进程访问页面不再<span class="GramE">”</span></font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“中时，会发生一次”</font></span><span lang="EN-US"><font face="Arial">Page Fault</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“且同时发生一次主存与虚拟内存之间的数据交换。综上所述，我们可以得出结论：</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">(a)</font></font></span><font style="font-size: 10.5pt"><span class="GramE"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”</font></span></span><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“不是进程内存消耗的全部；</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">(b)</font></font></span><font style="font-size: 10.5pt"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">所有进程<span class="GramE">”</span></font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“的和也不等有机器主存总的消耗量，因为存在”</font></span><span lang="EN-US"><font face="Arial">Working Shareable</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“与别的进程共享；</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">(c)</font></font></span><font style="font-size: 10.5pt"><span class="GramE"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”</font></span></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“太大会影响机器的运行速度，因为”</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“太大会导致机器的可用主存太少，从而导致将进程的老页面释放到虚拟内存，同时，进程”</font></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“中的页面减少后，使进程发生”</font></span><span lang="EN-US"><font face="Arial">Page Fault</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“的频率更高。因为在主存与虚拟内存之间交换数据需要时间，所以机器的运行速度要减慢。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">(d)</font></font></span><font style="font-size: 10.5pt"><span class="GramE"><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">”</font></span></span><span lang="EN-US"><font face="Arial">Working Set</font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体">“由于数据交换的存在，该指标是动态的，在测量的过程中会不断变化。（变化的最小单位为</font></span><span lang="EN-US"><font face="Arial">4K</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">）</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">所以<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Working Set</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“指标强调的是进程对机器主存的消耗，不是进程内存的全部信息。</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><font face="Arial"><font style="font-size: 10.5pt">&quot;Private Bytes&quot;</font></font></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><font face="宋体"><span style="font-family: ; background: none transparent scroll repeat 0% 0%; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;; mso-highlight: red"><font style="background-color: #ff0000"><font style="font-size: 10.5pt">该指标包含所有<span class="GramE">为进程</span>提交的内存，包括机器主存和虚拟内存，可以认为它是进程对物理内存消耗</font></font></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font style="font-size: 10.5pt">，</font><span style="background: none transparent scroll repeat 0% 0%; mso-highlight: red"><font style="background-color: #ff0000; font-size: 10.5pt">且该指标相对来说更加稳定。在程序产生内存泄漏时，该值一定是不断上涨的。</font></span></span></font></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"></span></p>
<p style="margin-bottom: 14px" class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"></span></span><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">综上所述，个人更倾向于使用<span class="GramE">”</span></font></font></span><font style="font-size: 10.5pt"><span lang="EN-US"><font face="Arial">Private Bytes</font></span></font><span style="font-family: ; mso-ascii-font-family: &#39;Times New Roman&#39;; mso-hansi-font-family: &#39;Times New Roman&#39;"><font face="宋体"><font style="font-size: 10.5pt">“来定量进程的内存消耗和分析进程的内存泄漏。</font></font></span></p>
</p></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/%e8%bd%ac%e8%bd%bd%e8%bf%9b%e7%a8%8b%e7%9a%84%e8%99%9a%e6%8b%9f%e5%9c%b0%e5%9d%80%e7%a9%ba%e9%97%b4.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MFC获得各种视图指针的方法[转载]</title>
		<link>http://www.buguw.com/mfc%e8%8e%b7%e5%be%97%e5%90%84%e7%a7%8d%e8%a7%86%e5%9b%be%e6%8c%87%e9%92%88%e7%9a%84%e6%96%b9%e6%b3%95%e8%bd%ac%e8%bd%bd.html</link>
		<comments>http://www.buguw.com/mfc%e8%8e%b7%e5%be%97%e5%90%84%e7%a7%8d%e8%a7%86%e5%9b%be%e6%8c%87%e9%92%88%e7%9a%84%e6%96%b9%e6%b3%95%e8%bd%ac%e8%bd%bd.html#comments</comments>
		<pubDate>Sun, 27 Mar 2011 13:57:43 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[WinSDK & MFC]]></category>
		<category><![CDATA[MFC]]></category>
		<category><![CDATA[指针]]></category>

		<guid isPermaLink="false">http://www.buguw.com/mfc%e8%8e%b7%e5%be%97%e5%90%84%e7%a7%8d%e8%a7%86%e5%9b%be%e6%8c%87%e9%92%88%e7%9a%84%e6%96%b9%e6%b3%95%e8%bd%ac%e8%bd%bd.html</guid>
		<description><![CDATA[获得各种视图指针如下 1) 在View中获得Doc指针 2) 在App中获得MainFrame指针 3) 在View中获得MainFrame指针 4) 获得View（已建立）指针 5) 获得当前文档指针 6) 获得状态栏与工具栏指针 7) 获得状态栏与工具栏变量 在Mainframe获得菜单指针 9) 在任何类中获得应用程序类 10) 从文档类取得视图类的指针(1) 11) 在App中获得文档模板指针 12) 从文档模板获得文档类指针 13) 在文档类中获得文档模板指针 14) 从文档类取得视图类的指针(2) 15) 从一个视图类取得另一视图类的指针 16)获取分割视图中各个视图的指针 VC中编程对于刚刚开始学习的同学，最大的障碍和问题就是消息机制和指针获取与操作。其实这些内容基本上是每本VC学习工具书上必讲的内容，而且通过MSDN很多问题都能解决。下面文字主要是个人在编程中指针使用的一些体会，说的不当的地方请指正。 一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架，无论是多文档还是单文档，都存在指针获取和操作问题。下面这节内容主要是一般的框架，然后再讲多线程中的指针使用。使用到的类需要包含响应的头文件。 首先一般获得本类(视，文档，对话框都支持)实例指针this，用this的目的，主要可以通过类中的函数向其他类或者函数中发指针，以便于在非本类中操作和使用本类中的功能。 1）在View中获得Doc指针 CYouSDIDoc *pDoc=GetDocument() //一个视只能有一个文档。 2) 在App中获得MainFrame指针 CWinApp 中的 m_pMainWnd变量就是MainFrame的指针也可以： CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd(); 4) 获得View（已建立）指针 CMainFrame *pMain=(CmaimFrame *)AfxGetApp()-&#62;m_pMainWnd; CyouView [...]]]></description>
			<content:encoded><![CDATA[<p>获得各种视图指针如下   <br />1) 在View中获得Doc指针    <br />2) 在App中获得MainFrame指针    <br />3) 在View中获得MainFrame指针    <br />4) 获得View（已建立）指针    <br />5) 获得当前文档指针    <br />6) 获得状态栏与工具栏指针    <br />7) 获得状态栏与工具栏变量    <br /> <img src='http://www.buguw.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> 在Mainframe获得菜单指针    <br />9) 在任何类中获得应用程序类    <br />10) 从文档类取得视图类的指针(1)     <br />11) 在App中获得文档模板指针    <br />12) 从文档模板获得文档类指针    <br />13) 在文档类中获得文档模板指针    <br />14) 从文档类取得视图类的指针(2)     <br />15) 从一个视图类取得另一视图类的指针    <br />16)获取分割视图中各个视图的指针</p>
<p>VC中编程对于刚刚开始学习的同学，最大的障碍和问题就是消息机制和指针获取与操作。其实这些内容基本上是每本VC学习工具书上必讲的内容，而且通过MSDN很多问题都能解决。下面文字主要是个人在编程中指针使用的一些体会，说的不当的地方请指正。</p>
<p>一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架，无论是多文档还是单文档，都存在指针获取和操作问题。下面这节内容主要是一般的框架，然后再讲多线程中的指针使用。使用到的类需要包含响应的头文件。</p>
<p>首先一般获得本类(视，文档，对话框都支持)实例指针this，用this的目的，主要可以通过类中的函数向其他类或者函数中发指针，以便于在非本类中操作和使用本类中的功能。</p>
<p>1）在View中获得Doc指针   <br />CYouSDIDoc *pDoc=GetDocument() //一个视只能有一个文档。    <br />2) 在App中获得MainFrame指针    <br />CWinApp 中的 m_pMainWnd变量就是MainFrame的指针也可以：</p>
<p>CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd(); </p>
<p>4) 获得View（已建立）指针   <br />CMainFrame *pMain=(CmaimFrame *)AfxGetApp()-&gt;m_pMainWnd; </p>
<p>CyouView *pView=(CyouView *)pMain-&gt;GetActiveView(); </p>
<p>5) 获得当前文档指针    <br />CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd-&gt;GetActiveDocument();</p>
<p>6) 获得状态栏与工具栏指针   <br />CStatusBar * pStatusBar＝(CStatusBar *)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_STATUS_BAR); </p>
<p>CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()-&gt;GetDescendantWindow(AFX_IDW_TOOLBAR); </p>
<p>7) 如果框架中加入工具栏和状态栏变量还可以这样   <br />(CMainFrame *)GetParent()-&gt;m_wndToolBar; (CMainFrame *)GetParent()-&gt;m_wndStatusBar; </p>
<p> <img src='http://www.buguw.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> 在Mainframe获得菜单指针   <br />CMenu *pMenu=m_pMainWnd-&gt;GetMenu(); </p>
<p>9) 在任何类中获得应用程序类用MFC全局函数AfxGetApp()获得。</p>
<p>10)从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题，我的体会特别是文字处理CEditView当产生多个视图类时，这个功能是非常需要的。</p>
<p>CDocument类提供了两个函数用于视图类的定位： GetFirstViewPosition()和GetNextView()</p>
<p>virtual POSITION GetFirstViewPosition() const; virtual CView* GetNextView(POSITION&amp; rPosition) const; </p>
<p>注意：GetNextView()括号中的参数用的是引用方式，因此执行后值可能改变。 GetFirstViewPosition()用于返回第一个视图位置（返回的并非视图类指针，而是一个POSITION类型值），GetNextView()有两个功能：返回下一个视图类的指针以及用引用调用的方式来改变传入的POSITION类型参数的值。很明显，在Test程序中，只有一个视图类，因此只需将这两个函数调用一次即可得到CTestView的指针如下（需定义一个POSITION结构变量来辅助操作）：</p>
<p>CTestView* pTestView; </p>
<p>POSITION pos=GetFirstViewPosition(); </p>
<p>pTestView=GetNextView(pos); </p>
<p>这样，便可到了CTestView类的指针pTestView.执行完几句后，变量pos=NULL,因为没有下一个视图类，自然也没有下一个视图类的POSITION.但是这几条语句太简单，不具有太强的通用性和安全特征；当象前面说的那样，当要在多个视图为中返回某个指定类的指针时，我们需要遍历所有视图类，直到找到指定类为止。判断一个类指针指向的是否某个类的实例时，可用IsKindOf()成员函数时行检查，如： pView-&gt;IsKindOf(RUNTIME_CLASS(CTestView)); 即可检查pView所指是否是CTestView类。有了以上基础，我们已经可以从文档类取得任何类的指针。为了方便，我们将其作为一个文档类的成员函数，它有一个参数，表示要获得哪个类的指针。</p>
<p>实现如下：</p>
<p>CView* CTestDoc::GetView(CRuntimeClass* pClass) </p>
<p>{ CView* pView; POSITION pos=GetFirstViewPosition(); while(pos!=NULL)</p>
<p>{ pView=GetNextView(pos); if(!pView-&gt;IsKindOf(pClass)) break; } if(!pView-</p>
<p>&gt;IsKindOf(pClass)){ AfxMessageBox(&quot;Connt Locate the View.\r\n <a href="http://www.VCKBASE.com&quot;);">http://www.VCKBASE.com&quot;);</a> return NULL; } return pView; } </p>
<p>其中用了两次视图类的成员</p>
<p>函数IsKindOf()来判断，是因为退出while循环有三种可能：</p>
<p>1.pos为NULL，即已经不存在下一个视图类供操作；</p>
<p>2.pView已符合要求。</p>
<p>1和2同是满足。这是因为GetNextView()的功能是将当前视图指针改变成一个视图的位置同时返回当前视图指针，因此pos是pView的下一个视图类的POSITION,完全有可能既是pos==NULL又是pView符合需要。当所需的视图是最后一个视图是最后一个视图类时就如引。因此需采用两次判断。使用该函数应遵循如下格式（以取得CTestView指针为例）：</p>
<p>CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView)); </p>
<p>RUNTIME_CLASS是一个宏，可以简单地理解它的作用：将类的名字转化为CRuntimeClass为指针。至于强制类型转换也是为了安全特性考虑的，因为从同一个基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要，但能避免一些可能出现的麻烦。</p>
<p>3.从一个视图类取得另一视图类的指针综合1和2，很容易得出视图类之间互相获得指针的方法：就是用文档类作中转，先用1的方法得到文档类的指针，再用2的方法，以文档类的视图定位函数取得另一个视图类。同样，可以实现成一个函数：（假设要从CTestA V i ew中取得指向其它视图类的指针）</p>
<p>CView* CTestA V i ew::GetView(CRuntimeClass* pClass) { </p>
<p>CTestDoc* pDoc=(CTestDoc*)GetDocument(); </p>
<p>CView* pView; POSITION pos=pDoc-&gt;GetFirstViewPosition(); </p>
<p>while(pos!=NULL)</p>
<p>{ </p>
<p>pView=pDoc-&gt;GetNextView(pos); </p>
<p>if(!pView-&gt;IsKindOf(pClass)) break; </p>
<p>}</p>
<p>if(!pView-&gt;IsKindOf(pClass))</p>
<p>{ </p>
<p>AfxMessageBox(&quot;Connt Locate the View.&quot;); </p>
<p>return NULL; </p>
<p>} </p>
<p>return pView; </p>
<p>} </p>
<p>这个函数和2中的GetView()相比，一是多了第一句以取得文档类指针，二是在GetFirstViewPosition()和GetNextView()前加上了文档类指针，以表示它们是文档类成员函数。有了此函数；当要从CTestA V i ew中取得CTestBView的指针时，只需如下：CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView)); </p>
<p>11）对于单文档中也可以加入多个文档模板，但是一般的开发就使用MDI方式开发多文档模板，其方法与上述视图的获取方法很接近，这里稍做解释，如果不清楚，请查阅MSDN，（以下四个内容（11、12、13、14）来源：<a href="http://sanjianxia.myrice.com/vc/vc45.htm）可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板的位置；利用该值来调用CWinApp::GetNextDocTemplate函数，获得第一个CDocTemplate对象指针。">http://sanjianxia.myrice.com/vc/vc45.htm）可以用CWinApp::GetFirstDocTemplatePostion获得应用程序注册的第一个文档模板的位置；利用该值来调用CWinApp::GetNextDocTemplate函数，获得第一个CDocTemplate对象指针。</a> POSITION GetFirstDocTemplate( ) const; CDocTemplate *GetNextDocTemplate( POSITION &amp; pos ) const; 第二个函数返回由pos 标识的文档模板。POSITION是MFC定义的一个用于迭代或对象指针检索的值。通过这两个函数，应用程序可以遍历整个文档模板列表。如果被检索的文档模板是模板列表中的最后一个，则pos参数被置为NULL。</p>
<p>12）一个文档模板可以有多个文档，每个文档模板都保留并维护了一个所有对应文档的指针列表。用CDocTemplate::GetFirstDocPosition函数获得与文档模板相关的文档集合中第一个文档的位置，并用POSITION值作为CDocTemplate::GetNextDoc的参数来重复遍历与模板相关的文档列表。函数原形为： viaual POSITION GetFirstDocPosition( ) const = 0; visual CDocument *GetNextDoc(POSITION &amp; rPos) const = 0; 如果列表为空，则rPos被置为NULL. </p>
<p>13）在文档中可以调用CDocument::GetDocTemplate获得指向该文档模板的指针。函数原形如下： CDocTemplate * GetDocTemplate ( ) const; 如果该文档不属于文档模板管理，则返回值为NULL。</p>
<p>14)一个文档可以有多个视。每一个文档都保留并维护一个所有相关视的列表。CDocument::AddView将一个视连接到文档上，将该视加入到文档相联系的视的列表中，并将视的文档指针指向该文档。当有File/New、File/Open、Windows/New或Window/Split的命令而将一个新创建的视的对象连接到文档上时， MFC会自动调用该函数，框架通过文档/视的结构将文档和视联系起来。当然，程序员也可以根据自己的需要调用该函数。 Virtual POSITION GetFirstViewPosition( ) const; Virtual CView * GetNextView( POSITION &amp;rPosition) cosnt; 应用程序可以调用CDocument::GetFirstViewPosition返回与调用文档相联系的视的列表中的第一个视的位置，并调用CDocument::GetNextView返回指定位置的视，并将rPositon的值置为列表中下一个视的POSITION值。如果找到的视为列表中的最后一个视，则将rPosition置为NULL.</p>
<p>15)从一个视图类取得另一视图类的指针这个应用在多视的应用程序中很多见，一般如果自己在主程序或者主框架中做好变量记号，也可以获得，还有比较通用的就是用文档类作中转，以文档类的视图遍历定位，取得另一个视图类。这个功能从本文第10项中可以得到。</p>
<p>16)获取分割视图中各个视图的指针</p>
<p>CSplitterWnd m_wndSplitter；</p>
<p>m_wndSplitter.CreateStatic(this, 1, 2)；//分割成一行两列</p>
<p>m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftPaneView), CSize(10， 10), pContext)；</p>
<p>m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRightPaneFrame), CSize(0, 0), pContext)； //获取左边视图的两种方法</p>
<p>CLeftPaneView* pLeftPaneView = (CLeftPaneView*) m_wndSplitter.GetPane(0,0); //上一句可以用下句代替： //</p>
<p>CLeftPaneView* pLeftPaneView = (CLeftPaneView *)GetActiveView(); //获取右边视图</p>
<p>pLeftPaneView-&gt;m_pRightPaneFrame = (CRightPaneFrame*) m_wndSplitter.GetPane(0,1); </p>
<p>&#160;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2010/02/26/5328800.aspx</p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/mfc%e8%8e%b7%e5%be%97%e5%90%84%e7%a7%8d%e8%a7%86%e5%9b%be%e6%8c%87%e9%92%88%e7%9a%84%e6%96%b9%e6%b3%95%e8%bd%ac%e8%bd%bd.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VC下显示JPG,BMP,GIF等格式图像[转载]</title>
		<link>http://www.buguw.com/vc%e4%b8%8b%e6%98%be%e7%a4%bajpgbmpgif%e7%ad%89%e6%a0%bc%e5%bc%8f%e5%9b%be%e5%83%8f%e8%bd%ac%e8%bd%bd.html</link>
		<comments>http://www.buguw.com/vc%e4%b8%8b%e6%98%be%e7%a4%bajpgbmpgif%e7%ad%89%e6%a0%bc%e5%bc%8f%e5%9b%be%e5%83%8f%e8%bd%ac%e8%bd%bd.html#comments</comments>
		<pubDate>Fri, 25 Mar 2011 07:54:33 +0000</pubDate>
		<dc:creator>tiger7456</dc:creator>
				<category><![CDATA[WinSDK & MFC]]></category>
		<category><![CDATA[图像]]></category>

		<guid isPermaLink="false">http://www.buguw.com/vc%e4%b8%8b%e6%98%be%e7%a4%bajpgbmpgif%e7%ad%89%e6%a0%bc%e5%bc%8f%e5%9b%be%e5%83%8f%e8%bd%ac%e8%bd%bd.html</guid>
		<description><![CDATA[在VC下显示JPG,BMP,GIF等格式图像的方法有两种： 方法一：用COM组件的 IPicture接口(vc)注：此接口不支持png图片 方法二：用GDI＋(VC) 用COM组件的IPicture接口(VC) 在OnPaint 或 OnDraw中加入下代码即可 (注意 屏蔽掉 CXXDialog::OnPaint CXX::OnDraw)： dc.SetBkMode( TRANSPARENT ); // COM 初始化 ::CoInitialize(NULL); CFile mFile; LONG nLength; //1 打开文件并获得文件的真实大小 if ( mFile.Open(filename, CFile::modeRead &#124; CFile::shareDenyNone )) &#38;&#38; ( ( nLength = mFile.GetLength() )&#62; 0 ) ) { //2 从堆中分配指定数量字节的一整块，这时系统无法提供零零碎碎的局部或全局的堆 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nLength ); LPVOID pvData = NULL; [...]]]></description>
			<content:encoded><![CDATA[<p style="line-height: normal"><font color="#2f3699"><font face="宋体"><font style="font-size: 12pt">在VC下显示JPG,BMP,GIF等格式图像的方法有两种：</font></font></font></p>
<p style="line-height: normal"><font face="宋体"><font color="#2f3699"><font style="font-size: 12pt">方法一：用COM组件的 IPicture接口(vc)</font></font><font color="#fe18ed"><font style="font-size: 12pt">注：此接口不支持png图片</font></font></font></p>
<p style="line-height: normal"><font color="#2f3699" face="宋体"><font style="font-size: 12pt">方法二：用GDI＋(VC)</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><font face="宋体"><strong><font style="font-size: 15pt">用COM组件的IPicture接口(VC)</font></strong></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">在OnPaint <wbr></wbr><wbr></wbr>或 <wbr></wbr>OnDraw中加入下代码即可 (注意 屏蔽掉 CXXDialog::OnPaint <wbr></wbr>CXX::OnDraw)：</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">dc.SetBkMode( TRANSPARENT );</font></font></p>
<p style="line-height: normal"><font color="#2a6823"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">// COM 初始化</font></font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">::CoInitialize(NULL); </font></font><wbr></wbr></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">CFile mFile;       <br /><wbr></wbr>LONG <wbr></wbr>nLength;</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font color="#1c6a30"><font style="font-size: 12pt">//1 打开文件并获得文件的真实大小         <br /></font></font><font style="font-size: 12pt"><wbr></wbr>if ( mFile.Open(filename, CFile::modeRead | CFile::shareDenyNone ))        <br /><wbr></wbr><wbr></wbr>&amp;&amp; ( ( nLength = mFile.GetLength() )&gt; 0 ) )        <br /><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr></font></font><font style="font-size: 12pt"><font face="宋体"><font color="#1c6a30">//2 从堆中分配指定数量字节的一整块，这时系统无法提供零零碎碎的局部或全局的堆         <br /></font><wbr></wbr><wbr></wbr>HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nLength );        <br /><wbr></wbr><wbr></wbr>LPVOID pvData = NULL;        <br /><wbr></wbr><wbr></wbr>if ( hGlobal != NULL )        <br /><wbr></wbr><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr><wbr></wbr></font></font><font face="宋体"><font style="font-size: 12pt"><font color="#1c6a30">//3 锁定全局内存对象并返回它的首地址         <br /></font><wbr></wbr><wbr></wbr><wbr></wbr>if ( ( pvData = GlobalLock(hGlobal) ) != NULL )        <br /><wbr></wbr><wbr></wbr><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30">//4 把文件内容读进全局内存对象的地址空间中</font>        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>mFile.Read( pvData, nLength );        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>mFile.Close();</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font color="#1c6a30"><font style="font-size: 12pt">//5 GlobalUnlock函数把以GMEM_MOVEABLE方式分配的内存对象的锁定计数器减1</font></font><font style="font-size: 12pt">       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>GlobalUnlock( hGlobal );</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font color="#1c6a30"><font style="font-size: 12pt">//6 从全局内存中创建stream对象，第二个参数指定当stream释放时是否自动释放全局内存</font></font><font style="font-size: 12pt">       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>IStream *pStm;        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>CreateStreamOnHGlobal( hGlobal, TRUE, &amp;pStm) ;</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font color="#1c6a30"><font style="font-size: 12pt">//7 创建一个新的picture对象并用stream对象中的内容初始化</font></font><font style="font-size: 12pt">       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>IPicture *pPic;        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>if( SUCCEEDED( OleLoadPicture( pStm, nLength, TRUE, IID_IPicture, (LPVOID*)&amp;pPic ) ) )        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30">//8 释放不要的stream对象并清空stream指针</font>        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pStm-&gt;Release();        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pStm=NULL;        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>OLE_XSIZE_HIMETRIC mWidth;        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>OLE_YSIZE_HIMETRIC mHeight;</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30" face="宋体"><font style="font-size: 12pt">//9 得到picture对象中图片的宽和高</font></font><font face="宋体"><font style="font-size: 12pt"><font color="#fe2310">（单位：毫米）         <br /></font><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic-&gt;get_Width( &amp;mWidth );        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic-&gt;get_Height( &amp;mHeight );</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">CRect rc;       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>GetClientRect( &amp;rc );        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>double fX,fY;</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30" face="宋体"><font style="font-size: 12pt">//10 GetDeviceCaps(HORZRES)得到<font color="#fe2310">屏幕</font>的宽度</font></font><font style="font-size: 12pt"><font face="宋体"><font color="#fe2310">(单位：像素)         <br /></font><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30">// <wbr></wbr><wbr></wbr><wbr></wbr>GetDeviceCaps(HORZSIZE)得到<font color="#fe2310">屏幕</font>的宽度</font></font></font><font face="宋体"><font style="font-size: 12pt"><font color="#fe2310">(单位：毫米)         <br /></font><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>fX = (double) dc.GetDeviceCaps(HORZRES) * (double)mWidth / ( (double)dc.GetDeviceCaps( HORZSIZE ) * 100.0 );        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>fY = (double) dc.GetDeviceCaps(VERTRES) * (double)mHeight / ( (double)dc.GetDeviceCaps( VERTSIZE ) *100.0 );</font></font></p>
<p style="line-height: normal"><font color="#2408b4"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr></font><font color="#fd200d" face="宋体"><font style="font-size: 12pt">P.S.使用上述的方法有时计算出来的像素值是不准确的，因此我们可以采用下面这种方法：</font></font></p>
<p style="line-height: normal"><font color="#2408b4"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">OLE_XSIZE_HIMETRIC mWidth;         <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>OLE_YSIZE_HIMETRIC mHeight; <wbr></wbr>          <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>//得到picture对象中图片的宽和高 <wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>          <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic-&gt;get_Width(&amp;mWidth );          <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic-&gt;get_Height( &amp;mHeight );          <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>CSize sz(mWidth,mHeight);</font></font></font></p>
<p style="line-height: normal"><font color="#2408b4"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr></font><font color="#21179b" face="宋体"><font style="background-color: #f5f44c; font-size: 12pt">//通过下面这个方法后sz中的值就成了相应的像素值       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><strong>dc.HIMETRICtoDP</strong>(&amp;sz);</font></font></p>
<p style="line-height: normal"><wbr></wbr>    <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font color="#1c6a30" face="宋体"><font style="font-size: 12pt">//11 把图像显示在dc中</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">if( FAILED( pPic-&gt;Render( dc.GetSafeHdc(), 0, 0, (DWORD)fX , (DWORD)fY , 0, mHeight, mWidth, -mHeight, NULL ) ) )       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>AfxMessageBox( _T(&quot;渲染图片失败&quot;) );</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>    <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>    <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font color="#1c6a30"><font style="font-size: 12pt">//12 释放不要的picture对象，并把指针清空</font></font><font style="font-size: 12pt">       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic-&gt;Release();        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>pPic=NULL;</font></font></p>
<p style="line-height: normal"><wbr></wbr><font color="#1c6a30"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//13 释放不要的全局内存对象，这个千万别忘了(32位程序不需要这行，系统会自动释放；16位程序一定要)</font></font></font><font style="font-size: 12pt">     <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr></font><font face="宋体"><font style="font-size: 12pt">FreeResource(hGlobal);</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">}       <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>else        <br /><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>AfxMessageBox( _T(&quot;从stream中装载图片失败&quot;) );</font></font></p>
<p style="line-height: normal"><wbr></wbr><wbr></wbr><wbr></wbr><font face="宋体"><font style="font-size: 12pt">}       <br /><wbr></wbr><wbr></wbr>}        <br /><wbr></wbr><wbr></wbr>else        <br /><wbr></wbr><wbr></wbr><wbr></wbr>AfxMessageBox( _T(&quot;分配内存失败&quot;) );        <br /><wbr></wbr>}        <br /><wbr></wbr>else        <br /><wbr></wbr><wbr></wbr>AfxMessageBox( _T(&quot;打开文件失败&quot;) );</font></font></p>
<p style="line-height: normal"><font color="#2a6823"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//操作结束后进行COM口释放</font></font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">::CoUninitialize();</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><font face="宋体"><strong><font style="font-size: 16.5pt">用GDI＋(VC)</font></strong></font></p>
<p style="line-height: normal"><strong><font face="宋体"><font style="font-size: 12pt">VC </font><wbr></wbr></font></strong></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">添加Gdiplus.lib到工程中</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">头文件中添加</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">#ifndef ULONG_PTR       <br />#define ULONG_PTR unsigned long* <wbr></wbr>//定义类型</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">#include &quot;Gdiplus.h&quot; <wbr></wbr>//包含gdi头文件        <br />using namespace Gdiplus; <wbr></wbr>//命名空间</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">添加类成员变量</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">GdiplusStartupInput m_gdiPlusInPut;       <br />ULONG_PTR m_gdiPlusToken;</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">构造函数中初始化GDI+</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">GdiplusStartup( &amp;m_gdiPlusToken,&amp; m_gdiPlusInPut, NULL );</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">析构函数中 //销毁GDI+</font></font></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">GdiplusShutdown(gdiplusToken);</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">OnPaint()中：</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//CDialog::OnPaint();       <br /><wbr></wbr>CPaintDC dc( this );</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//建立图形对象       <br /><wbr></wbr>Graphics mGraphics( dc.GetSafeHdc() );</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//装入图像文件</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">Image img( L&quot;./res/test.jpg&quot;, TRUE );</font></font>    <br /><wbr></wbr></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">//在指定区域pdestPoints显示图像 （根据背景大小按比例缩放）</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">CRect rcClient;       <br /><wbr></wbr>GetClientRect( &amp;rcClient );</font></font></p>
<p style="line-height: normal"><wbr></wbr>    <br /><wbr></wbr><font face="宋体"><font style="font-size: 12pt">BOOL bWidth = rcClient.Width() / img.GetWidth()&gt; rcClient.Height() / img.GetHeight();       <br /><wbr></wbr>if ( bWidth )        <br /><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr>mGraphics.DrawImage(&amp; img, 0, 0, rcClient.Width(), rcClient.Width() * img.GetHeight() / img.GetWidth() );        <br /><wbr></wbr>}        <br /><wbr></wbr>else        <br /><wbr></wbr>{        <br /><wbr></wbr><wbr></wbr>mGraphics.DrawImage(&amp;img, 0, 0, rcClient.Height() * img.GetWidth() / img.GetHeight(), rcClient.Height() );        <br /><wbr></wbr>}</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">//原始大小       <br />mGraphics.DrawImage(&amp;img, 0, 0, img.GetWidth(), img.GetHeight() );</font></font></p>
<p style="line-height: normal"><wbr></wbr></p>
<p style="line-height: normal"><strong><font face="宋体"><font style="font-size: 12pt">EVC下显示图片:</font></font></strong></p>
<p style="line-height: normal"><font face="宋体"><font style="font-size: 12pt">void CXXDlg::OnPaint()       <br />{        <br /><wbr></wbr>CPaintDC dc(this); // device context for painting</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">dc.SetBkMode( TRANSPARENT );       <br /><wbr></wbr>CBITmap mBitmap;        <br /><wbr></wbr>mBitmap.Attach( SHLoadImageFile( _T( &quot;./player.jpg&quot; ) ) );</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">BITMAP mInfo;       <br /><wbr></wbr>mBitmap.GetBitmap( &amp;mInfo );</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">CDC mPicDC;       <br /><wbr></wbr>mPicDC.CreateCompatibleDC( &amp;dc );        <br /><wbr></wbr>CBitmap* pOldBitmap = mPicDC.SelectObject(&amp; mBitmap );        <br /><wbr></wbr>dc.BitBlt( 0, 0, mInfo.bmWidth, mInfo.bmHeight,&amp; mPicDC, 0, 0, SRCCOPY );</font></font></p>
<p style="line-height: normal"><wbr></wbr><font face="宋体"><font style="font-size: 12pt">mPicDC.SelectObject( pOldBitmap );       <br /><wbr></wbr>mBitmap.DeleteObject();        <br />}</font></font></p>
]]></content:encoded>
			<wfw:commentRss>http://www.buguw.com/vc%e4%b8%8b%e6%98%be%e7%a4%bajpgbmpgif%e7%ad%89%e6%a0%bc%e5%bc%8f%e5%9b%be%e5%83%8f%e8%bd%ac%e8%bd%bd.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

