end中,这是非常简单的操作。您只需移动指向堆栈末尾的指针即可。另一方面,您 可以
我已经被告知很多次了。但是我不知道为什么...从堆分配内存时会涉及哪些额外费用?与硬件相关吗?它与CPU周期有关吗?这么多的猜测,但没有确切的答案...有人可以给我一些阐述吗?
就像“展开”所述,Heap数据结构比Stack更复杂。在我看来,当线程开始运行时,会将一些内存空间分配给该线程作为其堆栈,而进程中的所有线程都将共享堆。此范例需要一些额外的机制来管理每个线程对共享堆的使用,例如垃圾回收。我对吗?
因为堆是比堆栈要复杂得多的数据结构。
对于许多体系结构,在堆栈上分配内存只是更改堆栈指针的问题,即它是一条指令。在堆上分配内存涉及寻找足够大的块,对其进行拆分,以及管理“簿记”,该簿记允许诸如free()
之类的内容以不同的顺序进行。
当范围(通常是函数)退出时,保证分配在堆栈上的内存将被释放,并且不可能只释放其中的一部分。
[在您重新陈述展开答案的编辑中,您提到了“堆数据结构”。要非常小心,因为称为heap的数据结构与动态内存分配没有关系。很清楚,我将使用免费商店的更多语言律师术语。
正如已经指出的那样,堆栈分配需要增加一个指针,该指针通常在大多数体系结构上具有专用寄存器,并且释放需要相同数量的工作。堆栈分配也适用于特定功能。这使它们成为编译器优化的更好的候选者,例如预先计算堆栈上所需的总空间,并对整个堆栈帧进行单个增量。同样,堆栈具有更好的保证数据局部性。几乎总是保证堆栈的顶部位于高速缓存行内,并且正如我已经提到的,堆栈指针通常存储在寄存器中。在某些体系结构上进行优化的编译器甚至可以通过重用以前的堆栈帧中的参数来完全消除堆栈上的分配,这些参数是作为参数传递给更深层堆栈帧中的调用函数的。同样,堆栈分配的变量通常也可以提升为寄存器,从而避免分配。
相反,免费商店要复杂得多。我什至不打算开始讨论垃圾收集系统,因为那是一个完全不同的话题,这个问题是关于C语言的。通常,免费存储区中的分配和解除分配涉及几种不同的数据结构,例如空闲列表或块池。这些数据结构和簿记也需要内存,因此浪费了空间。此外,簿记记录经常与分配混合,从而损害了其他分配的数据局部性。从免费存储区中进行分配可能会涉及从底层操作系统请求更多的进程内存,通常是从某种形式的平板分配器中获取。]为了进行简单比较,并使用jemalloc-2.2.5和sloccount中的数字作为参考,jemalloc实现包含超过8800行C语言的源代码和另外700行以上的测试代码。这应该使您很好地了解免费存储分配和堆栈分配之间的复杂性差异:数千行C代码与一条指令。
此外,由于免费存储分配不限于单个词法范围,因此必须跟踪每个分配的生存期。同样,这些分配可能会跨线程传递,因此线程同步问题会进入问题空间。免费商店分配的另一个大问题是碎片化。碎片会导致许多问题:
整个过程空间的其余部分
end中,这是非常简单的操作。您只需移动指向堆栈末尾的指针即可。另一方面,您 可以
删除堆栈:删除堆栈很容易。只需向下移动堆栈指针在堆区域上删除:查找元素在堆上的存储位置(使用簿记),并在必要时合并两个相邻的空闲块;
end中,这是非常简单的操作。您只需移动指向堆栈末尾的指针即可。另一方面,您 可以
删除堆栈:删除堆栈很容易。只需向下移动堆栈指针在堆区域上删除:查找元素在堆上的存储位置(使用簿记),并在必要时合并两个相邻的空闲块;