文章目录
C++ 内存管理
图示如下:
code segment/text segment:.TEXT
文本段,也称为代码段或简称为文本段,是目标文件或内存中包含可执行指令的程序的一部分。
text段不仅包含函数,还有常量。
作为存储区域,文本段可以放置在堆或堆栈下方,以防止堆和堆栈溢出覆盖它。
Initialized Data Segment:.DATA
初始化数据段,通常简称为数据段。数据段是程序的虚拟地址空间的一部分,其包含由程序员初始化的全局变量和静态变量。
请注意,数据段不是只读的,因为变量的值可以在运行时更改。
该段可以进一步分类为初始化的只读区域和初始化的读写区域。
Uninitialized Data Segment:.BSS
未初始化的数据段,通常称为“bss”段,意思是“block started by symbol”。
此段中的数据在程序启动之前由内核初始化为0。
未初始化的数据从数据段的末尾开始,包含初始化为零或在源代码中没有显式初始化的所有全局变量和静态变量。
例如,变量声明为static int i; 将包含在BSS部分中。
例如,一个声明为int j的全局变量; 将包含在BSS部分中。
stack
栈:函数中的局部变量存在栈上,在函数结束后自动释放空间。栈空间比较有限。
heap
堆:堆是new class存放的地方,需要我们手动delete进行空间的释放。
堆区域从BSS段的末尾开始,并从那里增长到更大的地址。堆区域由malloc,realloc和free管理,可以使用brk和sbrk系统调用来调整其大小(注意使用brk / sbrk和单个“堆区域”不需要履行malloc / realloc / free的合同;它们也可以使用mmap实现,以将可能不连续的虚拟内存区域保留到进程的“虚拟地址空间”中。堆区域由进程中的所有共享库和动态加载的模块共享。
堆栈区别与优缺点:
1.栈中变量有程序自动管理,堆中变量由程序员手动释放。
2.栈的空间有限,堆的空间非常大。
参考:Memory Layout of C Programs - GeeksforGeeks
C++ static
对于函数中的变量,当我们在变量前加上static时,就是告诉了编译器将该变量放入静态数据区。函数退出时不会将该变量析构掉,当我们下次再调用改函数依然可以取得内存中的这个变量。
static 对于函数于变量其实比较类似,它限定了函数只能在当前的模块中使用。
对于全局变量,加上 static 关键字后该变量只能用于当前的文件。
全局变量和加上 static的全局变量都存放在静态数据区。
静态数据区有 .bss 和 .data。.bss 在编译时实际上不占据空间,只有在运行时才会由被分配空间。没初始化的全局变量存放在.bss段,初始化赋值的全局变量存放在.data段,对于初始化为0的全局变量,依然存放在.bss段。
new的过程。operator new->空间配置器->malloc->glibc的malloc/tcmalloc->brk/sbrk/mmap->new operator。问sbrk分配了内存空间吗?没有,只是在进程范围内提供虚拟内存合法访问地址。要mmu映射,缺页中断,物理内存分配。说了一下伙伴算法。
参考: