【内存分配与管理】关于堆、栈的思考
在上一篇文章中,我们深入探索了malloc的底层实现,看到了通用内存分配器如何在碎片与效率之间寻找平衡。然而,malloc仅仅管理着内存世界的一半版图——堆。理解内存分配的全貌,我们还需要认识另一个同样重要但哲学截然不同的领域:栈。 本文我们将跳出具体的分配器实现,从更高维度思考:为什么程序需要同时存在堆和栈这两种内存模型?它们的本质区别是什么?又是什么深层的设计哲学决定了它们各自的特性和限制? 总结概括【基本管理规则】 栈是内存连续的,栈上的内存由系统自动管理,其空间较小,栈上对象的生命周期严格受到作用域的限制。【优点】 优点在于栈内存的分配和释放基于移动栈指针实现,速度较快不需要担心内存泄露;并且由于永远遵循先进后出的规则回收,所以内存永远是连续的,不会产生内存碎片。【缺点】 但是,为了保证栈的高效,栈布局必须在编译期确定,因此栈对象的灵活性较差,不允许动态分配。 【示例】 比如函数调用的返回地址、函数参数、局部变量等都会存储在栈上,在函数调用时移动栈指针开辟函数栈帧,函数结束时通过移动栈指针来释放内存。 【基本管理规则】 堆是无序内存,需要由用户手动管理或是通过GC来管理,...
【内存分配与管理】malloc设计哲学
上篇文章中主要讲解了malloc底层的原理机制,本篇文章则侧重于讲解为什么malloc要这样设计 allocator要解决的核心矛盾在哪?allocator需要在有限的时间开销下,尽可能高效地利用虚拟地址空间,其必须在 分配/释放的时间复杂度 与 堆空间的碎片率(空间利用率) 之间做权衡 追求速度意味着: 为了快,allocator通常会使用固定内存大小块、此时可以做到O(1)分配,减少了遍历、合并和切割操作,更倾向于粗粒度管理内存块,比如fastbin和smallbin。但这样做的结果就是,由于不能切割,用户可能拿到“偏大的块”,导致内部碎片;同时由于不能频繁合并,在短时间内会导致外部碎片。速度增加—>碎片增多—->空间利用率下降 追求空间利用率意味着: 为了提高空间利用率,allocator必须做精细切割、频繁合并,通过遍历做best-fit并维护更复杂的数据结构(红黑树/ordered bins)。这样做的结果就是,malloc/free成本增大,多线程下锁竞争更严重。空间利用率升高—>时间开销增大 所以,ptmalloc的分...
【内存分配与管理】malloc原理剖析
前言当我们谈论程序性能时,总绕不开“内存”这个话题。内存管理如同程序的血脉系统,决定着程序的效率、稳定性和资源利用率。我们对内存的理解不能只停留在malloc/free、new/delete的简单调用层面,更要对其背后的机制以及设计缘由有所理解。 这是“内存分配与管理”系列的第一篇文章。我们将从最基础、也最重要的malloc开始,逐层揭开内存管理的神秘面纱。malloc不仅仅是C语言中的一个库函数,更是理解现代操作系统内存分配思想的窗口——它的设计哲学、实现策略、以及效率与通用性的权衡,构成了整个内存生态的基础。 在具体说malloc之前,我们先分清楚几个常见的概念:allocator、malloc和ptmalloc:malloc理解为分配内存的接口,allocator是一个负责内存分配和回收的具体策略实现。在Linux + glibc默认环境下,通过ptmalloc策略来实现(ptmalloc是一个名称);Google实现了tcmalloc策略,微软实现了mimalloc…. arenaptmalloc针对堆管理,最顶层的管理结构为malloc_state,...