01.堆和栈
1.堆(heap)
用于动态分配内存,位于BSS和栈中间的地址区域,由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的 malloc/free 造成内存空间的不连续,会产生碎片。(经常问如何解决内存碎片?)当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间,因此堆的效率比栈要低的多。注:与数据结构中的堆不是一个概念,但堆的分配方式类似于链表。
经常问如何解决内存碎片?
answer:
内存碎片会降低内存的利用率并影响系统性能,以下是一些解决内存碎片的方法:
一、采用合适的内存分配算法
- 伙伴系统算法:
- 该算法将内存按 2 的幂次方大小进行划分,在分配内存时,从合适的大小块中进行分配。
- 释放内存时,若相邻块也空闲则进行合并,从而减少外部碎片的产生。
- slab 分配器:
- 主要用于内核内存的分配管理,针对频繁分配和释放的小对象进行优化。
- 预先分配一些对象缓存,当需要分配特定大小的对象时,直接从对应的缓存中获取,避免频繁的内存分配和释放操作产生碎片。
二、内存整理
- 定期进行内存压缩:
- 可以将分散的内存块移动到连续的内存区域,从而消除碎片。但这个过程可能会影响系统的性能,需要在适当的时候进行,比如系统负载较低时。
- 动态调整内存布局:
- 根据系统的内存使用情况,动态地调整内存中各个进程的布局,将空闲的内存区域合并在一起,减少碎片。
三、控制内存分配和释放的策略
- 尽量避免频繁的小内存分配和释放操作:
- 因为频繁的小内存操作容易产生大量的碎片。可以考虑一次性分配较大的内存块,然后在内部进行管理和分配,减少外部碎片的产生。
- 合理规划内存使用:
- 在设计程序时,对内存的使用有一个清晰的规划,尽量按照一定的顺序进行内存分配和释放,避免随机的内存访问模式。
四、使用内存池技术
- 自定义内存池:
- 针对特定类型的对象或者特定大小的内存需求,创建自定义的内存池。
- 在程序启动时预先分配一定数量的内存块,当需要分配内存时,从内存池中获取,释放时归还到内存池,避免频繁地向操作系统申请和释放内存,减少碎片的产生。
- 利用现有的内存池库:
- 有很多成熟的内存池库可供选择,这些库通常提供了高效的内存管理功能,可以根据实际需求进行配置和使用。
2. 栈(stack)
由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中,这个被调用的函数再为它的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出。
@@@ Do or Do Not, There is No Try! @@@

浙公网安备 33010602011771号