(十)多大内存够用呢

(一)程序装载需要解决的问题

程序运行实际上是通过装载器将经过动态链接生成的可执行文件装载如内存,然后交给CPU去执行的,这种机制下我们需要解决两个问题:

  1. 可执行文件加载后占用的内存应该是连续的;
  2. 我们需要同时加载多个应用程序,且不能让程序自己规定在内存中加载的位置;

如遇满足这两个条件,就需要在内存中划出一片连续区域,分配给程序,并将程序地址和实际物理内存地址做一个映射。而我们把指令中的地址称为虚拟内存地址,将其映射到的硬件地址称为物理内存地址

(二)内存分段

这种找出一段连续的物理内存和虚拟内存映射的方式称为分段,这种方法有一个不足之处就是内存碎片问题;

假如计算机上物理地址是1~100,一开始分配如下:

A程序占用0~50;

B程序占用50~70;

C程序占用70~80;

剩余10,此时需要加载一个程序D需要30空间,此时我们将程序B卸载,整个内存有30空闲内存了,但是我们无法分配到连续的30内存,这种情况下我们只能使用内存交换,Linux系统的swap硬盘分区就是预留的用于内存交换的空间,先将C程序占用的内存空间写到磁盘,然后从50~80分配给程序D,再将80~90分配给程序C将其写回内存。而这个过程是和我们所了解的jvm的标记-整理算法比较类似。内存交换有一个问题就是硬盘访问速度太慢,因此当内存交换需要将一大段内存数据都写进硬盘,会导致机器卡顿。

扫描二维码关注公众号,回复: 11178155 查看本文章

(三)内存分页

对于内存交换所产生的问题,可以从两方面着手解决:

  1. 少出现一些内存碎片;
  2. 每次内存交换时,让需要交换的数据尽量少一点;

        具体做法就是,将整个物理内存空间切成一段段固定大小,其所对应的虚拟内存大小也被切分成一段段固定大小,再和物理内存映射起来,这样固定大小的内存段称。如此,虚拟内存和物理内存的映射不再是整段内存分页,而是按一个个页,分页尺寸往往远小于程序大小,因此,不再有不能使用的碎片,却只有一个个释放掉的小小的页。即使内存空间不够时,只需让现有程序释放少数页即可,由于这种骚操作每次交换内存的大小比较小,因此不会有卡顿问题。这种骚操作又和jvm的G1垃圾回收器类似。

        进一步,程序运行时也不需要一次性将全部程序加载到内存,只需在程序运行时,按需分段加载需要的指令和数据到内存即可。实际上在操作系统中当要读取的页没将数据加载到物理内存时触发来自CPU的缺页错误,操作系统会处理这个错误,将对应的数据从硬盘上加载到物理内存。如此,任何程序都不需要一次性加载完所有指令和数据,而是按需加载当前所需即可,我们也就可以运行大小超过内存的程序了。

        通过虚拟内存、内存交换、内存分页相结合,我们的程序就不再需要关心实际物理内存地址、大小和当前分配方案,且对程序的编写、编译、链接都是透明的。这种手段就是计算机软硬件开发中常用的加入间接层来屏蔽复杂性的方法。

猜你喜欢

转载自www.cnblogs.com/rxmind/p/12825326.html