现在的位置: 首页 > 综合 > 正文

内存分配问题(转)

2013年10月03日 ⁄ 综合 ⁄ 共 1170字 ⁄ 字号 评论关闭

在《高质量程序设计艺术》一书中看到关于内存分配的一段,感觉很经典,做个记录。内存的问题一直是编程中一个不得不考虑的问题,特别是在C/C++中,内存分配和释放一直是软肋了。有本《深入理解计算机系统》讲的也很不错,废话不多说了,看看就是

内存分配:
在很多环境中,操作系统会根据使用需求来动态调整程序的栈空间;而在其他环境中,在程序被加载的时候它的栈空间就被设置了硬性的限制,而这个限制是不能被突破的。堆内存空间的处理要复杂的多。一个程序完全可能不需要任何堆内存空间就可以运行,如果它永远不调用malloc或者其他调用malloc的函数。另一方面,另一个程序可能就需要大量的堆内存空间。为了满足此类不同的需求,程序在开始运行的时候并不分配堆内存,它负责使用诸如sbrk(unix)HeapAlloc(在windows上)等函数从操作系统请求大块的堆内存。每次堆内存请求都需要到操作系统内核走个来回,其代价市昂贵的。因此,语言的运行时系统通常会从操作系统申请大块的内存,并用一个大块的内存来满足多个通过语言的高层功能(mallocnew等)所做的请求。如下就是从NetBSDc库实现的malloc中摘取的操作系统接口代码:

static void

morecord(int
bucket)

{

      
register union overhead *op;

      
register long sz;      //
目标快的大小

      
long amt; //
要分配的大小

      

      
sz - 1 << (bucke + 3);

      
amt = sz + pagesz;

      
op = (union overhead *)sbrk(amt);

}

Sbrk调用会根据指定的数量来调整程序的“中断(break)”------它所分配的内存的结尾。请注意,对于许多语言与运行环境而言,将释放的堆内存返还给操作系统是非常困难的。热管程序的内存市顺序从操作系统获得的,正如sbrk系统调用所做的,那么程序释放的内存块在堆的末端组成一块联系区域的可能性市非常低的。那些允许任意做指针操作的语言(如CC++)热按这个问题变得更加严重了,因为这使得系统不可能移动已经分配的内存块来压缩堆。因此,很多运行时系统的实现甚至都不去尝试将被释放的内存返还给操作系统,前面我们看到的malloc实现就是一例。结果就是,在一些系统中,一旦一个程序的内存映像开始增长,它就永远不会收缩,所有被释放的内存块只能在特定的程序运行实例中被重用(或者被交换到磁盘上)。请注意这只是一个实现质量的问题,而不是确定的事实。例如,微软的C运行时库就会调用HeapFree将连续的空闲内存块还给操作系统。

 

关于内存映射和内存其他的问题,书中还有不少,以后在写笔记,推荐看看此书。

有什么好看法,可以畅所欲言。

抱歉!评论已关闭.