内存管理
内存管理,即是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。一个执行中的程式,譬如网页浏览器在个人电脑或是图灵机(Turing machine)里面,为一个行程将资料转换于真实世界及电脑内存之间,然后将资料存于电脑内存内部(在计算机科学,一个程式是一群指令的集合,一个行程是电脑在执行中的程式)。
相关简介[ ]
- 我们知道,一个有用简单的发展在虚拟内存内,一个程序(操作系统),持续的追踪实体位置再每一个资料区段,及移动资料在实体位置去改善效能及保证可靠性,对于每个用户层(user-level)的程式,操作系统分配一段虚拟内存空间,当行程起始时,不需要移动资料到实体装置间,资料存于磁盘内的虚拟内存空间,也不需要去配置主内存空间给该行程,他们是很自由的当使用者有需要用到时才会加载到主内存内。
- 内存管理对于编写出高效率的Windows程序是非常重要的,这是因为Windows是多任务系统,它的内存管理和单任务的DOS相比有很大的差异。DOS是单任务操作系统,应用程序分配到内存后,如果它不主动释放,系统是不会对它作任何改变的;但Windows却不然,它在同一时刻可能有多个应用程序共享内存,有时为了使某个任务更好地执行,Windows系统可能会对其它任务分配的内存进行移动,甚至删除。因此,我们在Windows应用程序中使用内存时,要遵循Windows内存管理的一些约定,以尽量提高Windows内存的利用率。
内存对象[ ]
- Windows应用程序可以申请分配属于自己的内存块,内存块是应用程序操作内存的单位,它也称作内存对象,在Windows中通过内存句柄来操作内存对象。内存对象根据分配的范围可分为全局内存对象和局部内存对象;根据性质可分为固定内存对象,可移动内存对象和可删除内存对象。
- 固定内存对象,特别是局部固定内存对象和DOS的内存块很类似,它一旦分配,就不会被移动或删除,除非应用程序主动释放它。并且对于局部固定内存对象来说,它的内存句柄本身就是内存对象的16位近地址,可供应用程序直接存取,而不必象其它类型的内存对象那样要通过锁定在内存某固定地址后才能使用。
- 可移动内存对象没有固定的地址,Windows系统可以随时把它们移到一个新地址。内存对象的可移动使得Windows能有效地利用自由内存。例如,如果一个可移动的内存对象分开了两个自由内存对象,Windows可以把可移动内存对象移走,将两个自由内存对象合并为一个大的自由内存对象,实现内存的合并与碎片回收。
- 可移动内存对象和可删除内存对象在存取前必须使用内存加锁函数将其锁定,锁定了的内存对象不能被移动和删除。因此,应用程序在使用完内存对象后要尽可能快地为内存对象解锁。内存需要加锁和解锁增加了程序员的负担,但是它却极大地改善了Windows内存利用的效率,因此Windows鼓励使用可移动和可删除的内存对象,并且要求应用程序在非必要时不要使用固定内存对象。
局部内存[ ]
局部内存对象在局部堆中分配,局部堆是应用程序独享的自由内存,它只能由应用程序的特定实例访问。局部堆建立在应用程序的数据段中,因此,用户可分配的局部内存对象的最大内存空间不能超过64K。局部堆由Windows应用程序在模块定义文件中用HEAPSIZE语句申请,HEAPSIZE指定以字节为单位的局部堆初始空间尺寸。Windows提供了一系列函数来操作局部内存对象。
- 分配局部内存对象
- 加锁与解锁
- 改变局部内存对象
- 释放与删除
全局内存[ ]
全局内存对象在全局堆中分配,全局堆包括所有的系统内存。一般来说,应用程序在全局堆中进行大型内存分配(约大于1KB),在全局堆还可以分配大于64K的巨型内存。
- 分配全局内存对象
- 加锁与解锁
- 修改全局内存对象
- 内存释放及其它操作
- 巨型内存对象
段介绍[ ]
Windows采用段的概念来管理应用程序的内存,段有代码段和数据段两种,一个应用程序可有多个代码段和数据段。代码段和数据段的数量决定了应用程序的内存模式,段的管理和全局内存对象的管理很类似,段可以是固定的,可移动的和可删除的,其属性在应用程序的模块定义文件中指定。段在全局内存中分配空间,Windows鼓励使用可移动的代码段和数据段,这样可以提高其内存利用效率。
- 代码段
代码段是不超过64K字节的机器指令,它代表全部或部分应用程序指令。代码段中的数据是只读的,对代码段执行写操作将引起通用保护(GP)错误,每个应用程序都至少有一个代码段,用户也可以生成有多个代码段的应用。实际上,多数Windows应用程序都有多个代码段。通过使用多代码段,用户可以把任何给定代码段的大小减少到完成某些任务所必须的几条指令。这样,可通过使某些段可删除,来优化应用程序对内存的使用。
- 数据段
每个应用程序都有一个数据段,数据段包含应用程序的堆栈、局部堆、静态数据和全局数据。一个数据段的长度也不能超过64K。数据段可以是固定的或可移动的,但不能是可删除的。如果数据段是可移动的,Windows在将控制转向应用程序前自动为其加锁,当应用程序分配全局内存,或试图在局部堆中分配超过当前可分的内存时,可移动数据段可能被移动,因此在数据段中不要保留指向变量的长指针,当数据段移动时,此长指针将失效。