内存分配问题(转)
2008-10-26 21:45
183 查看
在《高质量程序设计艺术》一书中看到关于内存分配的一段,感觉很经典,做个记录。内存的问题一直是编程中一个不得不考虑的问题,特别是在C/C++中,内存分配和释放一直是软肋了。有本《深入理解计算机系统》讲的也很不错,废话不多说了,看看就是
内存分配:
在很多环境中,操作系统会根据使用需求来动态调整程序的栈空间;而在其他环境中,在程序被加载的时候它的栈空间就被设置了硬性的限制,而这个限制是不能被突破的。堆内存空间的处理要复杂的多。一个程序完全可能不需要任何堆内存空间就可以运行,如果它永远不调用malloc或者其他调用malloc的函数。另一方面,另一个程序可能就需要大量的堆内存空间。为了满足此类不同的需求,程序在开始运行的时候并不分配堆内存,它负责使用诸如sbrk(在unix上)和HeapAlloc(在windows上)等函数从操作系统请求大块的堆内存。每次堆内存请求都需要到操作系统内核走个来回,其代价市昂贵的。因此,语言的运行时系统通常会从操作系统申请大块的内存,并用一个大块的内存来满足多个通过语言的高层功能(malloc、new等)所做的请求。如下就是从NetBSD的c库实现的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系统调用所做的,那么程序释放的内存块在堆的末端组成一块联系区域的可能性市非常低的。那些允许任意做指针操作的语言(如C和C++)热按这个问题变得更加严重了,因为这使得系统不可能移动已经分配的内存块来压缩堆。因此,很多运行时系统的实现甚至都不去尝试将被释放的内存返还给操作系统,前面我们看到的malloc实现就是一例。结果就是,在一些系统中,一旦一个程序的内存映像开始增长,它就永远不会收缩,所有被释放的内存块只能在特定的程序运行实例中被重用(或者被交换到磁盘上)。请注意这只是一个实现质量的问题,而不是确定的事实。例如,微软的C运行时库就会调用HeapFree将连续的空闲内存块还给操作系统。
关于内存映射和内存其他的问题,书中还有不少,以后在写笔记,推荐看看此书。有什么好看法,可以畅所欲言。
内存分配:
在很多环境中,操作系统会根据使用需求来动态调整程序的栈空间;而在其他环境中,在程序被加载的时候它的栈空间就被设置了硬性的限制,而这个限制是不能被突破的。堆内存空间的处理要复杂的多。一个程序完全可能不需要任何堆内存空间就可以运行,如果它永远不调用malloc或者其他调用malloc的函数。另一方面,另一个程序可能就需要大量的堆内存空间。为了满足此类不同的需求,程序在开始运行的时候并不分配堆内存,它负责使用诸如sbrk(在unix上)和HeapAlloc(在windows上)等函数从操作系统请求大块的堆内存。每次堆内存请求都需要到操作系统内核走个来回,其代价市昂贵的。因此,语言的运行时系统通常会从操作系统申请大块的内存,并用一个大块的内存来满足多个通过语言的高层功能(malloc、new等)所做的请求。如下就是从NetBSD的c库实现的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系统调用所做的,那么程序释放的内存块在堆的末端组成一块联系区域的可能性市非常低的。那些允许任意做指针操作的语言(如C和C++)热按这个问题变得更加严重了,因为这使得系统不可能移动已经分配的内存块来压缩堆。因此,很多运行时系统的实现甚至都不去尝试将被释放的内存返还给操作系统,前面我们看到的malloc实现就是一例。结果就是,在一些系统中,一旦一个程序的内存映像开始增长,它就永远不会收缩,所有被释放的内存块只能在特定的程序运行实例中被重用(或者被交换到磁盘上)。请注意这只是一个实现质量的问题,而不是确定的事实。例如,微软的C运行时库就会调用HeapFree将连续的空闲内存块还给操作系统。
关于内存映射和内存其他的问题,书中还有不少,以后在写笔记,推荐看看此书。有什么好看法,可以畅所欲言。
相关文章推荐
- C++程序内存分配的问题
- 二维数组的列排序 考虑问题的全局性 声明数组必须要分配内存并清零
- C语言基础之内存分配问题(修改)
- 这几天在研究java中的内存分配问题,谈谈堆栈
- C++内存分配问题汇总(多篇博客的总结)
- vector 容器使用时应该注意的内存分配问题
- C++中有三种创建对象 内存分配问题
- VC中结构体内存分配问题透析(sizeof)
- Android虚拟机(DVM)内存分配——内存溢出问题
- C/C++内存分配问题
- 一个C内存分配问题
- 启动regionserver失败内存分配不足问题
- 关于结构体的内存分配问题--sizeof(/*struct*/A)
- java --数组内存分配等问题
- [置顶] 《深入理解Java虚拟机》——垃圾收集器与内存分配策略问题
- C语言中内存分配问题:
- C++内存分配问题
- PHP变量内存分配问题记录整理
- C++中的成员变量的内存分配问题
- 深入讲解函数中分配内存问题