动态内存使用慢的原因是什么?
What is slower about dynamic memory usage?
我知道在堆栈上分配内存比在堆上分配内存快,但是为什么堆内存分配慢呢?是因为堆栈分配是连续的,所以缓存局部性导致了这个问题吗?它不是内存分配后的使用情况,而是分配哪个更慢的时间?
撇开缓存问题不谈,CPU堆栈只是一个堆栈,一个后进先出列表/队列。你把东西移走的顺序和放进去的顺序完全相反。你不会通过在它中间移除一些东西而在它上面留下洞。这使得它的管理非常简单:
memory[--stackpointer] = value; // push
value = memory[stackpointer++]; // pop
或者你可以分配一个大块:
stackpointer -= size; // allocate
memset(&memory[stackpointer], 0, size); // use
并释放它:
stackpointer += size; // free
你的堆OTOH没有后进先出属性。因此,它必须单独跟踪所有分配的块。这意味着,它必须有一些空闲块的列表和分配块的列表它需要在分配的时候寻找足够大的块,在释放的时候寻找指定的块,然后可能在这个过程中进行一些块分割和合并。简单堆栈不需要做这些。
这是两种分配和释放方式在算法上的显著差异。
缓存和显式调用将物理内存映射到虚拟地址空间也加起来,但如果你认为它们在两种情况下是相等的,你仍然有几个指令与几十到几百个指令的差异。
"更好"可能不是一个好方法来描述它,但通常在堆栈上分配内存比在堆上分配内存"更快"。你是对的,是内存的分配变慢了,而不是内存的使用变慢了。
堆分配往往较慢的原因是堆管理器需要做额外的工作:它们经常尝试找到与您请求的大小非常接近的现有内存块,并且在释放块时,它们通常检查相邻的内存区域,以查看它们是否可以合并。堆栈分配只是给指针添加一个值,仅此而已。
相关文章:
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 删除类成员的动态分配内存的最佳方法是什么
- 我在 2D 数组的动态内存分配中遇到了一些奇怪的代码C++? 请解释一下这是什么?
- 释放 std::vector 中指针内存的最有效方法是什么?
- 释放分配给大量矢量的内存的最有效方法是什么?
- 内存中的值是什么?
- 将内存分配给 2D 数组时,“new int*[rowCount];”的含义是什么?是 2D 数组,是指向数组的指针数组
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么
- 使用 CFFI 释放内存时"MemoryError: Stack overflow"是什么意思?
- 函数不受主内存约束的函数所需的复杂性是什么?
- 当某些错误可以接受时,顺序加载存储原子的内存顺序应该是什么
- 获取释放内存顺序与顺序一致性不同的实际示例是什么?
- 数组向量的内存布局是什么
- 跳过的内存地址是什么?
- C/C++ 三维数组如何在内存中存储,以及遍历它的最快方法是什么
- 在内存使用或编译时间方面更好的是什么
- 在Windows上打开文件的内存开销是什么?
- 内存泄漏的长期后果是什么?