`
totoxian
  • 浏览: 1030776 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

windows和linux的内存管理

 
阅读更多

windows的内存管理很是严谨,使用内存必须首先分配,当然每个操作系统都是这样,然而windows的严谨在于分配的过程,分为保留和提交两个阶段,其中保留的含义就是在进程的虚拟地址空间保留一块空间,不能用作他用,保留的概念是针对虚拟地址空间的,而提交的含义是将刚才保留的虚拟地址空间的虚拟内存块映射到物理内存,这里windows扩展了物理内存的含义,包括内存条代表的物理内存和磁盘页文件以及任何可以和真正的物理内存进行换入换出操作的后备存储,提交的概念其实就是一个映射,为了将虚拟内存变得可用而做的一个到实际物理存储的一个映射,就是将假的变真了。

windows的保留和提交两阶段方式涉及到几件事情,一个就是页表什么时候确立,我们可以设想一种合理的方式,就是在内存块保留的时候,不操作页表,仅仅将虚拟内存段插入到一个便于查找和插入,删除的数据结构中,而在提交阶段操作页表,当然此时内存不一定已经到了真正的物理内存,很有可能只在页文件中为之分配了一个slot而已,此情形下,页表的相关位就可以用来描述这个slot的位置以及别的信息,只要页表的存在位为0即可,这一点和linux可以一样,事实上,提交内存只是在扩展物理内存含义的前提下才表示映射物理内存,虚拟内存真正被映射到原始物理内存只有在该内存被访问的时候才会发生,这是绝对懒惰的。事实上我们可以看到windows的方式不够懒惰,linux没有保留和提交的概念,当一个执行绪调用mmap或者malloc或者brk等等不同层次的函数时,实际上就等于保留了内存区域,而只有在该内存被访问的时候,才会直接映射到物理内存而在这之前,根本不会将虚拟内存和物理的事实有任何联系,真对于假只有在不能再隐蔽事实的的时候才会显露,linux的内存管理是一种绝对的懒惰,访问内存其实就可以被看做内存提交。windows之所以采用这一种的方式来管理内存其实是为了用一种更加统一的方式去管理所有的内存,只要内存提交了,那么内存管理器就要跟踪这块内存,不管它在物理存储器还是在磁盘页文件。linux的方式看来更加不规范,linux使用页表来充当双面角色,既可以查找物理存储器又可以查找交换分区内存的位置,并且linux中没有一种机制来统一管理物理存储器和交换分区的空间,靠强大的文件系统功能和高效的内存管理和文件管理数据结构就可以轻易做到内存的高效换入换出,解除了物理存储器和交换分区的耦合,相反,在windows下,统一华丽的外表下扭曲着混乱不堪的繁杂,比如说如果想修改页文件的格式,那么必须涉及内存提交时的逻辑,而在linux中只需要换一个file_operations就可以了,统一华丽的外表完全不是仅仅带来了观感上的舒服,同样也付出了代价,比如平衡进程间内存数量的任务就交给了用户,其实用户只要可以在本进程内存分配和管理内存上保持高度灵活就可以了,进程间的内存平衡这样的任务显然是操作系统应该担负起来的,由于只要提交内存,或者在物理存储器或者在磁盘页文件会占据一定的空间,而这些空间是所有的进程共享的,如果一个进程疯狂的提交了过多的内存,那么别的进程就要忍饥挨饿,这一点上操作系统作为一个协调者实际上帮不上什么忙,顶多将贪婪者灭掉了事,物理内存在各个进程间的分配比例完全取决于进程自己而失去了别的进程的监督以及内核机制的协调,这一点看起来不如linux,在linux中内存管理模块尽量使内存在进程间公平的分配,即使一个进程自己分配了大量的内存,只要它不访问这些内存,这些内存连交换分区都不会占据更别说物理存储器了,当然如果这个贪婪的进程要是访问了这些内存,那结果就和windows一样了,从程序的行为应该很容易辨别出这个进程,不过不管怎样也比windows那种允许占着茅坑不拉屎的策略要好得多,虽然内存已经很便宜,但是对于同样增长的应用来讲内存仍然是稀缺资源,因此完全懒惰式的分配方式应该就是最节省的方式。

作为以上讨论的直接结果,我们来看一下两个系统中的堆栈。在windows中堆栈的分配是静态的,也就是说在PE文件中确定了线程堆栈的大小并且一般不能在运行时动态改变,在对堆栈进行管理的时候,windows使用了一种稍微复杂一点但是考虑的很周到的方法,windows尽力去保护自己的堆栈不会溢出,怎么保护呢?在《windows核心编程》上有详细的描述,大致就是说首先为你的堆栈确定一个大小,然后将这段如此大小的内存块的第一个和最后一个页面设置为保留,其余的页面遵循以下原则:假设堆栈向下增长,windows将依次把正在被使用的下一个页面设置为保护提交,当然正在被使用的页面肯定是提交的了,每当保护提交页面被访问时系统会得到通知,注意得到通知而不是出错信息,并没有什么严重的错误,因为保护提交页面可以被访问,它已经提交了,只不过由于具有保护属性,所有要告知系统这一件事,系统得知后可以将保护提交属性设置给后一个页面,依次类推,堆栈有着严格的顺序访问特性,就是说首先是高地址被访问,在略低的地址不被使用之前更低的地址不会被使用,当然除非你使用汇编语言完全脱离堆栈的概念,这样的话,线程的堆栈空间页面将按照从高到底的顺序一个个被提交,而紧接着被提交的页面将被设置为保护提交,直到最后,到达堆栈的末尾的时候,windows会检测到,此时不再将最后一个页面设置为保护提交,而是引发一个栈溢出异常。windows的这种机制的结果就是有效地保护了堆栈后面的数据不被堆栈数据覆盖,但是这种机制并不是每次都奏效的,比如一个足以使栈溢出的大数组分配在栈上,数组的起始其实已经出了堆栈,如果我直接存取这第一个元素的话,并且恰好该元素覆盖的内存已经被提交,那就完蛋了,如果你觉得上述实例会被编译器发现的话,那么考虑下面的例子:

char s[1];

s -= 100000;

*s = 100;

看看linux是怎么做的,很简单,十分懒惰,linux没有为堆栈分配静态的大小,而是利用缺页中断使得堆栈在运行期动态增长,当然没有了固定的大小也就不存在溢出的问题了,只要虚拟内存足够,动态增长的需求就有可能被满足,那么linux有没有什么办法来保护非堆栈数据被堆栈数据损坏或者反过来的情况呢?说实话,没有,主要是因为一来实现那个机制很复杂,维护引入的额外数据结构肯定会影响效率,二来这是用户空间的事情,程序员如果不合格直接开掉他就是了,内核不用为他擦屁股,实际上内核如果真的用雕虫小技帮他擦了屁股,没有会说内核很高明的,因此开源的linux没有这种复杂而且单单对内核没有什么用的机制,实际上如果程序员不合格,那么他写的程序是防不胜防的,机器能和人PK吗?很显然不能,再好的操作系统面对一般烂的程序员也是无力去爱谁啊!

最后讨论一下“如何分配内存以及在哪里分配到底要不要让用户看到”这个有点哲学味道的问题,这个问题关键要看分配的内存做什么用以及这种作用和系统机制的联系的紧密程度,比如说我需要一块内存保存一些我程序里面的结构,比如大型数据库缓冲,比如一个字符串,这种情况下分配越透明越好,因为程序没有必要和实现机制交流,这样程序可以更加集中精力解决所谓的业务问题,但是如果一块内存被一个管理机制需要,那么就有必要导出给用户更多的信息,因为这种需求往往都是关注实现本身的需求,而不是接口需求,比如线程栈的位置,因为线程是操作系统的一种机制,目的是优化程序执行,它其实和业务逻辑没有什么太大的关系,线程更多的被程序流程的管理机制使用而不是被业务流程使用。在这一点点上,linux要比windows好得多,看看clone系统调用的参数,用户必须为线程分配栈空间,而这在windows中却是被默默执行的,实际上windows尽力去向用户隐藏底层的很多重要的信息,然而类似线程栈的位置这样的信息很多用户空间的管理机制还是要用到的,因此最好将这一切都交给用户,系统不要管的太多。

分享到:
评论

相关推荐

    Linux内存管理 vs. Windows 2000内存管理

    Linux内存管理 vs. Windows 2000内存管理

    内存管理作业C++ 提供两个版本:windows平台和linux平台下运行

    提供两个版本:windows平台和linux平台下运行 注意:linux版本使用GCC编译连接运行 1. cd到source code目录 2.1 使用compile_shell shell script编译连接:./compile_shell 2.2 使用Makefile文件 编译连接:make 3. ...

    Linux下的内存管理

    Linux是一种可以在PC上执行的类似UNIX的操作系统,功能非常强大,甚至超过了Windows操作系统。它可用来开发出优秀的图形化界面,并有免费的中文套件,支持在Linux系统下显示和使用中文。 Linux系统有极稳定的基本...

    深入理解Linux虚拟内存管理 英文版 PDF

    深入理解Linux虚拟内存管理,ISBN:9787810777308,作者:(爱尔兰)戈尔曼著;白洛等 作者简介 · · · · · · Mel Gorman曾获得爱尔兰利马瑞克大学的计算机学士和硕士学位。他的研究领域广泛:从网页开发到摄影...

    Linux系统内存使用经验

    Linux的内存管理,实际上跟windows的内存管理有很相像的地方,都是用虚拟内存这个的概念,文中介绍了在Linux下查看内存用的command free命令,并对反回的参数进行解释。

    史上最佳体验的windows和linux远程连接工具,比Xshell更好用的 FinalShell

    1.多平台支持Windows,Mac OS X,Linux 2.多标签,批量服务器管理. 3.支持登录Ssh和Windows远程桌面. 4.漂亮的平滑字体显示,内置100多个配色方案. 5.shell,sftp同屏显示,同步切换目录. 6.命令自动提示,智能匹配,输入更...

    C 语言实现的内存池 mpool.c : 适用于Windows和Linux

    当C/C++程序频繁分配内存...很多语言提供了这个基础设施,这里我提供一个C语言的版本mpool.c:原始的mpool仅仅提供Unix/Linux的版本,我增加了Windows的版本,这样这个mpool就成为适用于Windows和Linux的完整的版本了。

    linux和windows对比

    linux windows对比ppt,从进程,内存管理着手,便于理解2者的区别

    嵌入式系统/ARM技术中的Linux 内存管理机制简介

    这是Linux内存管理的一个优秀特性,在这方面,区别于 Windows的内存管理。主要特点是,无论物理内存有多大,Linux 都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的...

    操作系统实验报告 模拟内存管理

    Linux文件操作与内存管理算法模拟 1、实验目的: 1) 熟悉LINUX文件系统; 2) 通过编写文件操作的程序,进一步掌握操作系统的文件管理机制。 3) 模拟内存管理算法的实现方法; 4) 掌握简单的用户接口(字符菜单)...

    windows和linux下Maven私服nexus-3.27.0-03搭建

    maven私服必备神器,该压缩包包含最新版的nexus安装包,含windows和linux版。 Nexus 是Maven仓库管理器,如果你使用Maven,你可以从Maven中央仓库 下载所需要的构件(artifact),但这通常不是一个好的做法,你应该...

    内存管理内存管理内存管理

    C 和 C++,您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 追溯到在 Apple II 上进行汇编语言编程的时代,那时内存管理还不是个大问题。您实际上在运行整个系统。系统有...

    P2P-LINUX-80211-c标准库-windows内存管理-统计自然语言.rar

    2012-05-26 09:21 24,101,382 windows内存管理.zip 2012-05-26 09:26 27,003,769 统计自然语言处理基础(中文版).pdf 2012-05-26 09:34 33,704,040 C标准库-中文.pdf 2012-05-26 09:10 42,060,748 802.11无线网络权威...

    nexus-3.27.0-03包含windows和linux

    该压缩包包含最新版的nexus安装包,含windows和linux版。 Nexus 是Maven仓库管理器,如果你使用Maven,你可以从Maven中央仓库 下载所需要的构件(artifact),但这通常不是一个好的做法,你应该在本地架设一个Maven...

    glibc内存管理ptmalloc源代码分析

    本文通过Glibc的内存暴增问题,主要介绍了系统的内存管理问题,具体如下: 目录 1. 问题 2. 基础知识 2.1 X86平台Linux进程内存布局 2.1.1 32位模式下进程内存经典布局 2.1.2 32位模式下进程默认内存布局 ...

    linux操作系统大全

    10.内存管理 11.进程通信 12.PCI 13.中断和中断处理 14.设备驱动程序 15.文件系统 16.网络系统 17.系统内核机制 18.linux内核编程模块 19.有关进程通信的编程 20.高级线程编程 21.linux网络编程 22.linux IO编程 23....

    操作系统(内存管理)

    文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文中将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半...

    操作系统实验模拟内存管理算法

    模拟FF,WF,BF内存管理算法,有紧缩处理,排序处理,碎片处理。Windows下,Linux下均可运行。

    WindowsPhone8内存调研

    主要是调查了windows phone8的内存管理以及与linux的android的内存管理的对比。

    跨平台内存管理代码

    跨平台(Windows/Linux)内存管理源代码,基于C编写 实现内存堆管理、malloc、free等常用内存管理功能

Global site tag (gtag.js) - Google Analytics