00:00
是,嗯,每个进程都有一个4GB的一个虚拟内存,然后这是个4G4GB内存的话,我们都知道,就是搞两句是共享的,对吧?嗯,搞两句是共享的。嗯勾两句嗯共享的,然后呢,第两句嗯私有的对吧?嗯然后按这种说法的话,你可以想一下,像我呃目前电脑的内存条好像是八个G,嗯,那也就是说我嗯就算他高两句是共享的,那我是不是就开开四个进程。嗯,开四个进场,嗯开四个进场,嗯,我的呃内存条就已经满了,就没办法再去看内存了,因为我内存条不够了,对吧,那你可以看一下,我现在桌面上已经看你的超出四四个进程了,对吧?什么腾讯课堂,还有录屏文件,还有这个WPS,它很明显就已经超出了我们这个刚才说的四个进程,那也就是说他这个第两句这个私有的,他也没有完全的使用,那Windows它是怎么管理的,呃,表面上它是给你呢一个4GB的内存。
01:26
嗯,表面上给了你4GB内存,但是我们可以想一下,假设我这个程序我什么都没干,我就输出了一句话普F对吧,我我就一个普F啊,输出一个一,他有必要给你申请四这个4GB内存嘛,勾2G是共享的对吧,那低两句呢,你就输出一句话,而且就打印一个一,他就没有必要去给你申请啊两个G内存对吧,也就是说,嗯,操作系统的话,操作系统只有你真正使用到这这块内存的时候啊,才会真正的给你申请物理内存,因为我们都知道,我们这个虚拟的4GB内存,它就是一个虚拟出来的,只是有一个概念,但是它这个虚拟内存未必能对应到我们的一个内存条上,嗯,就可以。
02:27
理解为这个虚拟内存,它是不是肯定会映射到我们这个物理内存上,这物理内存呢?你就可以先假设它是一个内存条。正常我们认为对吧,它这个呃是一个映射关系,和这个物理虚拟内存和物理内存。虚拟内存和物理内存,但是你当你他给你虚拟内存的时候,未必就给你申请了这个物理内存的一个空间,也就是说,呃,当你真正去定义出来一个变量,或者是你去使用它的时候,它才会给你申请这个物理内存的一个空间,才会给你把虚拟内存和物理内存做一个映射,那当你这些黄色部分都没有使用呢,那你就个为了它其实就没有占用这个物理内存,那这样的话,它是不是就腾出了空间,嗯,就能多去,嗯嗯创建出来这个内存,那之后呢,我们就可以有了这个概念,之后的话,呃,我们可以扩展一下,就是物理内存的话,就是我们Windows之前讲过,嗯,在保护模式的时候就已经讲过,在学汇编的时候,Windows是以夜视管理的,嗯,页页管理内存,然后页呢基本都是四兆内。
03:47
存,但其实不完全都是四兆对吧,嗯,啊,不是四兆啊,4KB,但凡不一定都都是这个,嗯,4KB内存它也有大页和小页对吧?嗯,也就是说它这个物理内存的话,它会拆开。
04:13
对吧,一个页一个页去管理。他是这样的。嗯,然后呢,去映射我们的一个虚拟内存。啊,它是这种去管理的,嗯,然后在嗯Windows下就是对于申请内存,申请内的API,就是我们的常用的对吧,Vlo和这个create file mapping。啊,只有这两个API能去申请内存,还有一个扩展版的ex,对吧,它是给别的那个内存去申请空间的,然后呢,虚拟内存它也只有两种,一种就是visual alo申请出来的是一个私有内存,还有呢,可fair mapping呢,它申请出来的是共享内存啊在Windows下面的话,它只有这两种,呃,属性没有别的,你像说之前我们新件家用的那些麦lo,它它的本质其实就是已经他他是不会申请内存的,麦lo和这个new啊,是不会申请内存的,它是在你已经申请好的内存中再去划分给你。
05:42
啊,这个他是不会真正的去申请内存啊,他申请出来的内存其实就是呃,用了你已经申请好的内存,嗯,再去给你划分,没有去真正的意义上去申请内存,嗯,然后的话,我们就可以去去看一下私有内存是什么样的呢?私有内存的话就很简单对吧?呃,当你去这个定义出来一个变量之后,定义变定义出来一个变量之后,嗯,然后呢,它肯定会给你找到对应的物理页对吧,这个就是我的物理液,它给就可能给你分到了零差1000的位置,那什么是共享内存呢?就比如说我现在又定义出来一个变量in特B,嗯,定义成20,然后呢,他给你分到了物理页为零,零差2000的位置,嗯。
06:31
然后这个你B的一个虚拟内存的位置可能是在A进程当中的,呃,零叉45678这个位置,然后呢,你能访问到这个呃20对吧,也就是这个B的变量,那在这个其他的进程当中呢,什么?因为它是共享内存对吧?那这个零差2000的位置,它就可能被映射到了,被进成了嗯,被进成了abcd啊就比如说啊,就嗯零差12345吧,它可能映射到了B0差12345的位置,然后呢,也也存储的一个B对吧?嗯,为20的一个空间,那这个就是共享对吧,就是大家一起共享一个物理液,只是被映射到的内存空间是不一样的,然后我们就可以去用一下这几个API,知道这些概念之后。
07:24
嗯,然后把这个去创建一下这个进程。嗯,我就创建这个控制台,嗯,控制台应用。嗯,然后我肯定是要包含这个Windows头文件对吧?嗯,然后一会儿我要放给他,放到虚拟基地,然后我们好观察啊,我改一下,然后把代码生成改成MTD。
08:06
然后刚才说了,嗯,然后我先去打个暂停,嗯,刚才说了能申请内存空间呢,真正意义上的申请内存只有两个API的吧,一个是微lo,还有一个是be mapping。然后我们一个一个去观察,然后我们就可以一进到这个官方文档的一个说明。啊,第一个就是问你对吧,你要去申请,呃,申请的一个内存空间的一个地址,但是我们现在肯定是不知道哪哪些空间。申没申请对吧,我们是不知道的,所以第一个参数的话,我们一般都是填空,填空的话就是操作系统会默认帮我们去,嗯,去这个找空余的位置,那第一个参数我没有填空,第二个参数的话,就是你要填的一个大小,因为大小的话一般都是刚才说了操作系统是以夜市管理的,就是说你申请一个字节啊,就像刚才这个。
09:16
这个图。嗯,图应该是叫互关了是吧,就像这个图,你你就算去申请一个字节对吧,你就算申请了一个int变量,嗯,他也会给你分分配一个页的啊,4096这么大小的一个什么,嗯空间,所以说我们这个一般都填零差1000,嗯然后的话就是一个属性看一下。这个属性的话是什么意思啊,一般我们都会填提交或者是保留啊,提交或者保留,呃,提交的话就是代表着嗯,既给你既给你分配的啊虚拟内存也也提交了物理页啊,就像我们刚才画的这个图,你如果填的是提交,也就是我们这么个红,它呢,既给你分配的就是虚拟内存。
10:26
然后呢,他也给你映射到了物理页当中,那这个就是提交的意思,嗯,那这个保留呢,他就是光给你光给你申请了什么虚拟内存,但是呢,物理页当中没有你这个位置,只是给你申请了虚拟内存,你什么时候用到了这个虚拟内存,他才给你分配物理页,嗯,就这么个意思,然后呢,我们先可以看一下,嗯,我们申请两个变量嘛,申请两个,然后呢,第二个先保留。嗯,然后的话就是啊,你这个属性就是可读可写的一个属性,然后呢,我们就是可以写一个。
11:08
嗯,读写。嗯,读写啊,可读可写可执行,然后我们填一下这个红。然后他的他的一个返回值是什么,就是我们的一个嗯地址,嗯,然后我们都去打印一下啊,百分号P,白分号P。啊,这是我的第一个地址对吧,然后我再打印一下,第二个地申请内存的一个地址,然后我们还暂停一下,然后我们去生成一下,然后我们给他放到虚拟机当中。
12:14
怎么中毒了呢?嗯,然后然后就是我们还得说一下,嗯,他既然你可以想一下,它基本有四个G,就是虚拟内存,它是有四个GB对吧,每个进程都有有4GB,它肯定操作系统会管理的这个虚拟内存的一个4GB,然后操作系统呢,就是用一个叫vad,一个搜索阿尔法素,阿尔法术去管理的我们的虚拟内存,然后我们就可以去观看这个二叉树,对吧,便利这个二叉树,看看我这个内存的一个空间,然后呢,我先运行一下我这个程序,但是他好像被改网了是吧?然后嗯,我我这样,我先现在我还没有申请内存对吧,因为我在这个这个位置打了一个暂停,现在还是没有申请内存呢,啊,然后我就去去便利一下它的一个空间。
13:20
我现便利一下。所有正常。嗯。然后我们等一下啊。
14:02
嗯,找到我们这个这个程序对吧?嗯,然后呢,我就去看一下这个进程的一个详细信息,感到好science,嗯,他对吧,看一下他的详细信息,然后我们等一会儿,他好像还有没有便利出来。然后这个vad物,就是刚才说的它那个它的一个什么,呃,这个二进程的一个二塔素,然后呢,我点一下。啊,然后我们就可以给他拷贝出来对吧,然后可以看一下这个就是它进程当中使用的一个虚拟内存的一个情况,对吧,然后我们看一下现在它它的什么位置都被申请了,嗯,幺零的位置,203040对吧,然后我们现在嗯给他勾起来。勾起来之后的话,你就回到虚拟机对吧,然后我去,然后你可以看一下他申请了两两块内存对吧,然后我们现在我们再给他暂停一下。
15:10
然后呢,我们重新去便利这个数对吧。然后呢,拿过来,然后我们可以对比一下,刚才你可以看到他这个虚拟机里打印出来的是什么药D,对吧,药地和妖异,然后我们看一下有没有药帝和妖异在这个位置,对吧,他申请出来了。这两个位置,然后你可以看一下上面第一次变利的时候,他是不是没有这个妖帝和妖异的位置,然后你可以看一下他这个啊,他这个属性是不是私有的这个位置,对吧?它实有内存,然后呢,一虚拟内存什么什么属性对吧?可读可写可执行,然后你可以看一下我在外面写的代码,第一个我是不是写的提交啊,那你可以看一下它是不是有一个这个位置,它是不是唯一,那这个唯一就是代表你已经提交了,那零呢,就是代表没提交,就是没有对应的物理液,那这行代码的话,它就是提交了,它就有对应的一个物理,那这个就是,嗯,虚拟内存。
16:19
虚拟内存,然后是有属性对吧,那刚才还说了还有一个可谓mapping,这个它是可以共享的。然后呢,我们也我们也写一下。然后呢,你也可以看一下文档。然后你可以看一下,它第一个参数是要一个文件句柄,那它这个可以共享什么,它可以共享文件,嗯,就是在这个位置。嗯,我们最开始不说了吗?他这个是怎么共享文件,嗯,然后就假设是一个物理内存对吧?呃,它它是可以和文件进行一个绑定,进行一个映射的,因为我们都知道,嗯,去访问文件的时候,操作文件它这种外设的东西的话,它这个IO是请求是非常慢的啊,于于是呢,他就发明了这个API,就可以什么假设我现在有一个文件。
17:18
啊,这个是文件,我就可以和这个物理页去绑定一起,因为我们操作内存是非常快的,对吧,他就可以把文件的这些数据,比如说SD这些东西啊,放到什么这个物理内存上啊,放到物理内存上之后。然后呢,物理内存和我这个虚拟内存再进行一个绑定。嗯,物理内存和虚拟内存再进行一个绑定,对吧,然后呢,我们再给他拿到虚拟内存当中,然后我去操作这块虚拟内存,就等于操作这个文件,那我第一个这个第一个参数,刚才我们看到的第一个参数,如果我要不填,我填一个无效的句柄的话,那就是单单存的啊,就是一个嗯,申请内存。
18:07
然后呢,我们现在是不绑定文件对吧,那我就可以给他填一个无效的句柄,对吧,无效的句柄。啊,第二个参数就是什么,是否继承的一个标志。然后我的一个什么页面保护是吧。嗯,页面保护我们还是可读可学可直行吗?就全全写了,嗯,然后就是高32和低32,因为这个文件,这个文件要映射的文件大小肯定有可能是超过4GB的,对吧,所以说他分了一个高低位,高低32位进行个组合,那我们现在高位肯定是没有的,对吧,然后低位的话我们也可以,嗯。地位的话,我们先填个呃256吧,啊或者零差1000对吧?啊,然后就是一个名字,因为我是共享内存,因为你你进你的进程二,因为我们现在这个位置它是共享的对吧?啊共享那那你既然共享的话,那别的进程是怎么找到这块,呃,物理内存的,它就是通过这个名字,所以说你如果想往你的其他进程啊,也能找到这块内存的话,你就可以给它起个名字,比如说我起个啊test的吧。
19:37
那最后呢,它就会返回什么啊一个句柄,呃,这行API一旦执行完的话,就是我们内内存数据,他就已经,嗯,已经给我们申请了这个物理内存,嗯,然后呢,你肯定是需要给他绑定对吧。
20:00
建行只是申请了物理内存,然后您需要进行一个物理内存和虚拟内存的绑定,那绑定的话你可以去window Windows也可以去查这个API。叫map view of这么个APIAPI,呃,他这个文档下头应该写了。嗯,你可以看一下,你可以看到吗。这个API就可以映射到我这个虚拟内存当中,然后他这个也有案例对吧,创建这个文件映射,你可以看一下对吧,这个什么A进程和B进程。啊,你可以看到这是A进程对吧,然后这是B进程,然后你可以看一下它是不是也用了这个API,然后呢,第一个参数就比较简单了,嗯,就管你要这个什么映射类的一个句柄啊第二个参数的话就是,呃,应该也是一个属性吧,我们看一下。
21:18
啊,我就可以直接什么可读可写对吧。嗯,全部,嗯,第三个参数的话,就是你那个映射从哪开始映射对吧,我们填零的话,他就肯定是从零开始映射,然后映映射多少对吧?我们填零的话应该是映射全部,我们看一下填零的话是不是映射全部。啊,如果是参数为零对吧,一直映射到这个文件尾部,然后我们填填零就可以了,嗯,然后的话,它会返回一个什么,嗯,我们的一个虚拟内存的一个地址,然后我们也可以打印一下。
22:12
嗯,之后的话就是,嗯,你可以你可以去什么关闭映射,最后对吧,你肯定要把这个资源给他释放掉啊关闭映射那首先肯定是先解除我们那个虚拟内存的映射对吧,然后呢,把我们的地址拿进来,然后最后再close handle对吧?啊关掉是吧,我们的一个句柄handle啊,我们的handle在哪啊,在这啊这是A进程对吧。对吧,也能正常的申请内存,嗯,然后的话,我们先写一个什么共享对吧,嗯,然后我们可以进行一个s tr copy,我们往这个内存地址去写一个什么,嗯,Hello word吗。
23:17
然后我我应该得把那个SDL给它关掉,找一下。呃,常规里。然后我在这打个暂停。然后我再创建一个B进程,因为它这个内存是可以共享的,对吧,然后再创建一个B进程。呃,控制台。毕竟场。
24:04
呃,B进场的话,刚才然后我们也给他改一下啊。嗯。然后。常贵。那B进场的话肯定是,呃,想访问这个内存,我肯定是现在要找到你那个物理内存对吧,那刚才这个文档上应该也有在这个位置对吧?嗯,然后他说了B进程直接用open fair map屏,我们打开这个曲柄,打开曲柄之后同样进行一个映射啊就可以了。然后我就我就直接拷贝代码了,这个就没有什么难度了,然后同样的包含这个Windows头文件。然后打开对吧,然后他的一个权限,还有一个什么,是否继承标志,然后你要打开它那个名字对吧,我们叫test。
25:01
然后呢,我们起个handle handle对吧,那之后呢,它也是需要进行一个映射的。然后把它拿过来,拿过来之后我们就直接嗯嗯弹一个对话框嘛,麦box啊,或者直接不打F,把分号S一下,刚才刚才然后把这个地址拿过来,然后我看看我这个位置有没有杠零。嗯。看一下啊。嗯,我们现运行界面。对吧,然后我们单步调试一下。对吧,句柄有,然后地址也是有的,对吧,我们看一下对吧,Hello hello word,然后F10你可以看到hello word出来了,那这个就是一个共享内存对吧,然后它是你也可以去刚才啊虚拟基地看一下我们这个属性,它确实是一个嗯,共享的一个属性,然后呢,你可以给他。
26:16
啊,同样给他拿到这个虚拟机里对吧。啊,共享的属性就是像他这个什么,呃,Map这种类型,它就是一个共享的标志。然后你拿到虚拟机里。嗯。然后我们直接运行嘛,我们就不不看了。诶,我看一下啊,呃,这好像。我先把这几行处试掉啊,然后重新生成一下。
27:05
然后给他拿过来。啊嗯,D0的位置对吧,然后你就可以去便利这个竞争。嗯,有点慢啊。然后找到他对吧,然后我们看一下这个进程的一个什么,详详详详细信息对吧。
28:04
嗯。嗯。往后看一下啊。呃,他。拿过来。然后我们看一下他这个数对吧,但是他还得便利那个进程切换的一个环境,然后我们等一会儿。啊,好的,然后我们点一下这个,就是看你这个虚拟内存对吧,然后咱再编低我们的虚拟内存,然后刚才那个地址是多少呢?D0的吧,那你看一下D0的位置,你可以看到这个属性,看到了吗?共享属性,然后你可以看到像他这些共享后面的话都会共享一些文件,对吧?那这种这种是怎么出来的,你调用一下load library,然后你再看一下你的内存就知道了,因为我们都知道,呃,像那些user sa那些库函数对吧,还有nt de这种这种东西它是可以被挂钩的呢,但是你可以发现你把这个你呼克调,呃,比如说你呼克一下message box,你只是影响你自己的一个进程啊,不会影响其他进程,那他这种你可以看一下他这种属性的话,就是斜好位。
我来说两句