内存分配责任
Memory allocation responsibility
我一直在思考这个问题,但还没有找到任何解释。
哪个模块决定应该为C++程序分配多少内存?是操作系统决定编译器的建议吗?连接?
分配的内存中堆栈和堆的比率是多少?
对于不同的操作系统,答案是不同的。通常,可执行文件包含主线程所需的堆栈大小,由链接器放置在那里,它可能作系统设置覆盖。可以通过一种或多种方式配置操作系统设置,可能是按用户配置的。某些操作系统不需要预先指定堆栈大小,它们可以在使用堆栈时添加堆栈,或多或少是无限期的(直到达到硬限制或系统耗尽可用内存)。那些确实需要预先调整大小的人最初可能只分配地址空间而不是内存,并在堆栈达到该远时将地址映射到内存。
堆通常不会预先分配,因此没有"堆栈和堆的比率"。分配给进程的总内存可能会也可能不会受到限制 - 如果没有,那么它可以在系统资源允许的范围内增加,或者在 32 位系统上可能会受到可用地址空间的限制。
C++标准中的那种问题。 它依赖于编译器和操作系统。
有关链接器生成的类型示例,操作系统在确定程序请求的资源时需要考虑该类型,请参阅:
http://en.wikipedia.org/wiki/Executable_and_Linkable_Format#ELF_file_layout
在某些情况下,有一些 API 专门用于从操作系统请求资源:
在使用 GNU 编译器编译期间更改 Linux 中C++应用程序的堆栈大小
还有一些方法可以告诉操作系统在某些环境中设置配额和限制:
https://stackoverflow.com/questions/4983120/limit-memory-usage-for-a-single-linux-process
设置 Windows 进程(或用户)内存限制
如果您想对某个操作系统如何管理资源使用情况进行实证研究,您可能会使用进程监视器实用程序更好地了解它,而不是寻找文档......尤其是使用闭源操作系统。
取决于您的程序和操作系统。 通常,在启动时,只分配足够的内存来保存可执行文件,任何只读数据,并且通常大约4k用于堆栈。 然后,当您调用 malloc 或 new 来分配内存时,您将获得虚拟内存空间,而无需任何物理内存备份它。 这称为延迟分配,只有在实际写入内存时,才会对内存进行物理分配。
编译和计时以下内容以了解我在说什么:
//justwrites.c
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = calloc(sizeof(int),19531); // number of writes
return 0;
}
// deadbeef.c
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000); // allocate 8 million bytes
// immediately write to each page to simulate all at once allocation
// assuming 4k page size on 32bit machine
for ( int* end = big + 20000000; big < end; big+=1024 ) *big = 0xDEADBEEF ;
return 0;
}
// bigmalloc.c
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes
return 0;
}
至少对于 32 位窗口,每个进程都有自己的地址空间副本,2G 用户 2G 内核(由所有进程共享),虚拟内存子系统确保访问相同位置的进程为其进程获取适当的数据。这就是程序可以具有相同的入口点并多次运行,同时不踩踏具有相同可执行文件的其他进程正在使用的数据的方式。
应用程序将继续使用更多的虚拟内存,内核将为该进程分配更多的物理内存,直到物理内存耗尽,交换空间/分页文件。您可以通过系统调用限制进程可以使用的内存。
堆栈和堆几乎总是在可用内存的两端分配,因此堆栈从可用内存的顶部向下增长,而堆从底部增长(此决定取决于体系结构)。这允许它们单独增长,以便需要大量堆但不多堆栈的程序可以使用与需要大量堆栈但不太多堆的程序相同的计划。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 内存分配责任